Delphi compatible LCG Random

From Free Pascal wiki
Jump to navigationJump to search

Delphi compatible random numbers

Many Freepascal programmers also maintain sourcecode in Delphi.
Even if you have moved to Freepascal from Delphi you may have data that relies on Delphi's Random.
Here are cross-platform functions that generate Delphi-identical pseudo-random numbers given the same RandSeed:

unit lcg_random;
// Delphi compatible LCG random number generator routines for Freepascal.
// (c)2017, Thaddy de Koning. Use as you like
// Algorithm, Delphi multiplier and increment taken from:
// https://en.wikipedia.org/wiki/Linear_congruential_generator
// The default Delphi RandomSeed is determined as zero.
{$ifdef fpc}{$mode objfpc}{$endif}

interface

function LCGRandom: extended; overload;inline;
function LCGRandom(const range:longint):longint;overload;inline;

implementation

function IM:cardinal;inline;
begin
  RandSeed := RandSeed * 134775813  + 1;
  Result := RandSeed;
end;

function LCGRandom: extended; overload;inline;
begin
  Result := IM * 2.32830643653870e-10;
end;

function LCGRandom(const range:longint):longint;overload;inline;
begin
  Result := IM * range shr 32;
end;

end.


A small demo

program lcgdemo;
// Compile and run in both Delphi and FPC and compare the output.
// It is exactly the same
{$ifdef fpc}{$mode objfpc}
{$Macro on}{$define random := LCGRandom}
{$endif}
{$ifdef mswindows}{$apptype console}{$endif}
uses lcg_random;

var i:integer;
begin
  RandSeed := 999;  // default delphi randseed is zero
  for i := 1 to 20 do
  begin
    write(Random(100):4); // Delphi: Random FPC:LCGRandom. See macro
    if i mod 5 = 0 then writeln;
  end;

  RandSeed := 999;  // default delphi randseed is zero
  for i := 1 to 20 do
  begin
    write(Random:4:8,' ');// Delphi: Random FPC:LCGRandom
    if i mod 5 = 0 then writeln;
  end;
  Readln;
end.

See also

  1. LCG on wikipedia
  2. Generating Random Numbers

See also