Помощь новичкам

…или открывает новые горизонты: проект IL2CPU – .NET coding on bare metal!

См. также C# Open Source Managed OS (COSMOS)

Щупал еще (давно) .NET Core с флагом native. Но оно так и не взлетело. Не знаю, какие щас там успехи.

Люблю я наших планов громадьё!
  (В. Маяковский)
1 лайк

Можно как-то подружить Lazarus с паскалем АБС ?

смысл - сам редактор и подсветка мне в лазарусе существенно удобнее, чем в АБС.

т.е. чтоб писать в лазарус, а код компелировался в паскаль АБС.

(Вопрос из зала) – Профессор, а можно ли скрестить ежа с ужом?

Можете просто писать код в редакторе Лазаруса, сохранять его, а затем запускать в ABC. Я так с C# делаю.

1 лайк

Если Вы пишете именно про Pascal ABC - проект, закрытый 10 лет назад и фактически бывший windows-реализацией языка Turbo Pascal, то нельзя: Lazarus базируется на Free Pascal, который шире Turbo Pascal. А если Вы называете таким именем PascalANC.NET, Вас могут не понять, как минимум. Ну а подружить - пишите кросс-компилятор. PascalABc.NET совместим с FreePascal но не гарантировано на 100%.

1 лайк

Очевидно же, что речь именно об ABC.NET.

1 лайк

Мне - нет. Я не привык додумывать, что именно хотел сказать человек. Если Вам нравится этим заниматься, попробуйте порезвиться с задачами школьников - тут постоянно приходится думать, о чем это они вообще

1 лайк

Тем временем, почитывая MSDN насчёт постоянных изменений расчёта хэша

Вроде всё понятно и логично – человеческая “универсальность” абстрактна, но не увидел актуального сравнения скорости/распределения и пригожести для тех или других типов данных. В частности, обрабатывая большие объёмы текстов, хотелось бы избежать лишних коллизий, поэтому интересует работа с текстовыми строками и что лучше для PABCNET.

Примечательно, что в MS прислушались к гласу народа и начиная с .NET 4.5 хэши могут учитывать домены:

if (HashHelpers.s_UseRandomizedStringHashing)
   return string.InternalMarvin32HashString(this, this.Length, 0L);

Тесты чего? Как можно применять этот GetHashCode?

1 лайк

@Admin Есть ли способ добавлять файл манифеста? Мне понадобилось дать моей программе высокий уровень UIPI (для SAC, иначе программы с высоким уровнем UIPI игнорируют команды SAC), но я не нашёл решения без этого файла манифеста.

Как и указано в вопросе – актуальные тесты скорости и распределения (как пригожести для длинных строковых данных Unicode). Другими словами, нужен стабильный специализированный хеш именно для string.GetHashCode.

Насчёт применения – как и указано в статье по ссылке на MSDN – применяется автоматически для вставки и поиска/сравнения дериватов класса Dictionary<TKey,TValue> и Hashtable после соответствующего переопределения/override виртуальных методов Equals и GetHashCode. То есть, это замена стандартного (сравнительно медленного и зависящего от версии .NET) хеширования (не путать с шифрованием System.Security.Cryptography.HashAlgorithm и System.Security.Cryptography.KeyedHashAlgorithm) на любой пользовательский алгоритм. Например, в статье рекомендуют для большей лавинообразности (противоколлизии) использовать смещение-влево-с-переносом, а пока почитываю и покуриваю.

Если подумать, то в хеше также нужно учитывать длину строки… И обратная задача – как оптимальнее по хешу находить похожие строки?

Насчёт стабильности - она уже нормальная вроде у стандартного string.GetHashCode. На msdn вроде пишут только что у пользовательских типов это может работать нестабильно:

type
  t1 = record
    x, y: integer;
    constructor(x, y: integer) :=
    (self.x,self.y) := (x,y);
  end;

begin
  writeln(t1.Create(2,4).GetHashCode);//одинаковые
  writeln(t1.Create(3,5).GetHashCode);
  writeln;
  
  var hs := new HashSet<t1>;
  hs.Add(new t1(2,4)).Print;//True
  hs.Add(new t1(3,5)).Print;//True
end.

Но, как видите, HashSet прекрасно справляется с 2 разными записями, имеющими одинаковый хеш-код. Наверное, это работает медленнее, но всё равно работает. А с классами - даже если у 2 разных экземпляров одинаковые значения, хеш-код будет всё равно разный.

Что касается строк - из за того, что две одинаковых строки обычно имеют общий адрес в памяти - можно определять хеш-код по адресу. Как то так:

type
  HashableString = class
    
    s: string;
    
    public function GetHashCode: integer; override;
    begin
      var h := System.Runtime.InteropServices.GCHandle.Alloc(s, System.Runtime.InteropServices.GCHandleType.Pinned);
      var i64: uint64 := h.AddrOfPinnedObject.ToInt64;//наверное можно как то лучше, незнаю
      h.Free;
      
      var hi: cardinal := i64 shr 32;
      var li: cardinal := i64 and $FFFFFFFF;
      Result := hi xor li;
    end;
    
    constructor(s: string) :=
    self.s := s;
    
  end;

begin
  HashableString.Create('abc').GetHashCode.Print;
  HashableString.Create('abc').GetHashCode.Println;
  HashableString.Create('ab'+('c'*1)).GetHashCode.Print;//другой адрес, потому что мы не в виде константы определили эту строку
  HashableString.Create('ab'+('c'*1)).GetHashCode.Println;//и тут тоже какой то новый
  HashableString.Create('abc').GetHashCode.Print;
end.

Но, наверное, стандартное string.GetHashCode всё же будет быстрее и возможно даже более стабильно…

1 лайк

может кому-то из начинающих пригодиться (а то я весь мозг сломал) : по удалял весь свой огород и вот как оказалось проще создавать объекты из массива и находить их. (я упрощенно написал)

uses Graph3D;

begin
 var шарики := new List<SphereT>;
  var объект3Д: Object3D;
      for var i := 1 to 10 do  //вместо массива
      begin
        шарики.Add(Sphere(i+1,0,2,1));
      end;
      Graph3D.OnMouseUP += procedure (x, y, mb) -> begin 
      объект3Д := FindNearestObject(x, y);
        if объект3Д = шарики[1] then View3D.Title := 'шарик1';
        if объект3Д = шарики[2] then View3D.Title := 'шарик2';
        if объект3Д = шарики[3] then View3D.Title := 'шарик3';
        end;
end.

Мне, как минимум, просто интересно ))) Спасибо.

а как в 3д окне вывести 2д статичный текст? кроме этого способа?

View3D.Title := 'тут текст';

мне нужно как-то вывести несколько строк

и еще вопрос, почему прога 2 сообщения выше работает, а эта нет? (вылетает у меня при клике на объект)

uses Graph3D;

begin
  var шарики := new List<SphereT>;
  var объект3Д: Object3D;
  for var i := 1 to 10 do
  begin
    шарики.Add(Sphere(i + 1, 0, 2, 1));
  end;
  Graph3D.OnMouseUP += procedure (x, y, mb) -> begin
    объект3Д := FindNearestObject(x, y);
    
    for var n := 1 to 10 do
    begin
      if объект3Д = шарики[n] then
      begin        
        View3D.Title := IntToStr (n);
      end;
    end;

  end;
end.

Потому что индексация элементов списка начинается с 0, а не с 1 – в вашем случае индексы должны быть от 0 до 9.

    for var n := 0 to 9 do
      if объект3Д = шарики[n] then
        View3D.Title := IntToStr(n+1);
1 лайк

@Admin, @ibond, нужда всё ещё не пропала… Есть для этого директива? Если нет, есть какие то проблемы с её добавлением?