Difference between revisions of "Delphi compatible LCG Random"
From Free Pascal wiki
Jump to navigationJump to searchm |
|||
(19 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=== Delphi compatible random numbers === | === Delphi compatible random numbers === | ||
− | Many Freepascal programmers also maintain | + | Many Freepascal programmers also maintain sourcecode in Delphi.<br> |
Even if you have moved to Freepascal from Delphi you may have data that relies on Delphi's Random.<br> | Even if you have moved to Freepascal from Delphi you may have data that relies on Delphi's Random.<br> | ||
− | Here are | + | Here are cross-platform functions that generate Delphi-identical pseudo-random numbers given the same RandSeed: |
− | <syntaxhighlight> | + | <syntaxhighlight lang=pascal> |
− | unit | + | unit lcg_random; |
// Delphi compatible LCG random number generator routines for Freepascal. | // Delphi compatible LCG random number generator routines for Freepascal. | ||
// (c)2017, Thaddy de Koning. Use as you like | // (c)2017, Thaddy de Koning. Use as you like | ||
Line 10: | Line 10: | ||
// https://en.wikipedia.org/wiki/Linear_congruential_generator | // https://en.wikipedia.org/wiki/Linear_congruential_generator | ||
// The default Delphi RandomSeed is determined as zero. | // The default Delphi RandomSeed is determined as zero. | ||
− | {$mode objfpc} | + | {$ifdef fpc}{$mode objfpc}{$endif} |
interface | interface | ||
− | function | + | function LCGRandom: extended; overload;inline; |
− | function | + | function LCGRandom(const range:longint):longint;overload;inline; |
implementation | implementation | ||
− | function IM: | + | function IM:cardinal;inline; |
begin | begin | ||
RandSeed := RandSeed * 134775813 + 1; | RandSeed := RandSeed * 134775813 + 1; | ||
Line 25: | Line 25: | ||
end; | end; | ||
− | function | + | function LCGRandom: extended; overload;inline; |
begin | begin | ||
Result := IM * 2.32830643653870e-10; | Result := IM * 2.32830643653870e-10; | ||
end; | end; | ||
− | function | + | function LCGRandom(const range:longint):longint;overload;inline; |
begin | begin | ||
Result := IM * range shr 32; | Result := IM * range shr 32; | ||
Line 36: | Line 36: | ||
end.</syntaxhighlight> | end.</syntaxhighlight> | ||
+ | <br> | ||
+ | A small demo | ||
+ | <syntaxhighlight lang=pascal> | ||
+ | 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.</syntaxhighlight> | ||
+ | === See also === | ||
+ | #[https://en.wikipedia.org/wiki/Linear_congruential_generator LCG on wikipedia] | ||
+ | #[[Generating Random Numbers]] | ||
+ | |||
+ | == See also == | ||
+ | * [http://en.wikipedia.org/wiki/Linear_congruential_generator Wikipedia article on the linear congruential generator algorithm] | ||
+ | |||
+ | [[Category:Statistical algorithms]] | ||
+ | [[Category:Modelling and Simulation]] |
Latest revision as of 04:53, 25 July 2019
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.