Аналог Random() из .NET

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Аналог Random() из .NET

Сообщение Lucifer » 11.11.2025 09:50:41

Понадобилось тут перенести одну тулзу с C# на Lazarus. Ибо очень уж она стала прожорливой в плане места. Сотня строк кода - и 85 мегабайт исполнимый файл, если его как автономный собирать. А именно так и надо, бо тулза должна без СМС и регистрации работать везде. В том числе и на яблодевайсе. И уперся я в этот самый пресловутый Random(), который на Lazarus никак не желал выдавать правильную последовательность. В общем, если кому надо - берите.
Код: Выделить всё
type
  TDotNetRandom = class
  private
    const
      MBIG = 2147483647;     // int.MaxValue
      MSEED = 161803398;
      MZ = 0;
    var
      SeedArray: array[0..55] of Integer;
      inext, inextp: Integer;
  public
    constructor Create(Seed: Integer);
    function Sample: Double;  // [0.0, 1.0)
    function Next: Integer; overload;
    function Next(MaxValue: Integer): Integer; overload;
    function Next(MinValue, MaxValue: Integer): Integer; overload;
  end;

constructor TDotNetRandom.Create(Seed: Integer);
var
  ii, mj, mk, i, k: Integer;
  subtraction: Integer;
begin
  if Seed = Low(Integer) then
    subtraction := High(Integer)
  else
    subtraction := Abs(Seed);

  mj := MSEED - subtraction;
  SeedArray[55] := mj;
  mk := 1;

  for i := 1 to 54 do
  begin
    ii := (21 * i) mod 55;
    SeedArray[ii] := mk;
    mk := mj - mk;
    if mk < 0 then
      mk := mk + MBIG;
    mj := SeedArray[ii];
  end;

  // Важно: 4 цикла, НЕ 5!
  for k := 1 to 4 do
    for i := 1 to 55 do
    begin
      SeedArray[i] := SeedArray[i] - SeedArray[1 + (i + 30) mod 55];
      if SeedArray[i] < 0 then
        SeedArray[i] := SeedArray[i] + MBIG;
    end;

  inext := 0;
  inextp := 21;
end;

function TDotNetRandom.Sample: Double;
var
  temp: Integer;
begin
  Inc(inext);
  if inext >= 56 then inext := 1;

  Inc(inextp);
  if inextp >= 56 then inextp := 1;

  temp := SeedArray[inext] - SeedArray[inextp];
  if temp < 0 then
    temp := temp + MBIG;

  SeedArray[inext] := temp;

  Result := temp * (1.0 / MBIG);
end;

function TDotNetRandom.Next: Integer;
begin
  Result := Trunc(Sample * MBIG);
end;

function TDotNetRandom.Next(MaxValue: Integer): Integer;
begin
  if MaxValue <= 0 then
    Exit(0);

  Result := Trunc(Sample * MaxValue);
end;

function TDotNetRandom.Next(MinValue, MaxValue: Integer): Integer;
begin
  if MaxValue <= MinValue then
    Exit(MinValue);

  Result := MinValue + Next(MaxValue - MinValue);
end;
Lucifer
постоялец
 
Сообщения: 131
Зарегистрирован: 05.01.2014 21:39:03
Откуда: Новороссийск

Re: Аналог Random() из .NET

Сообщение Alex2013 » 11.11.2025 11:32:19

Спасибо ! Действительно может пригодится (Сейчас не нужно но может понадобится если я например самодельную "Стабильную Диффузию " попробую сделать )
Зы
Кстати интересная тема!
"Сделал свой Stable Diffusion с нуля на Tensorflow. Это проще, чем кажется."
https://www.youtube.com/watch?v=HUmn2YmMe0Q
Сделал нейросеть Генератор картинок по тексту. Можете попробовать ее! Часть 2
https://youtu.be/zrSU1XwNggg
Нейросети для изображений на Tensorflow. Классификация, перенос обучения, fine-tunung.
https://youtu.be/jT8RJIC8vWk
VQ-GAN: нейросеть, давшая начало всем Dalle и Stable Diffusion. Разбираем принцип и делаем сами.
https://youtu.be/cMSWo3yZA7A
(Вообщем есть мысль что если переписать это безобразие в Лазарусе то все будет "летать и крякать" )
Зы Зы
Для чего это вообще нужно? Ну как бы это сказать... "Для всего " От автокорреляции данных до генерации карт и текстур для игр с "открытым миром" .
Alex2013
долгожитель
 
Сообщения: 3194
Зарегистрирован: 03.04.2013 11:59:44


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1