// The "Mother-of-all Pseudo Random Number Generators"
// Invented by Dr. George Marsaglia, Florida St. Univ., Dept. of Statistics
// Assembly implementation by Agner Fog
// Delphi BASM conversion, v1.0, (c)1999, EFD Systems
// Excellent statistical properties and extremely long
// cycle length (approx. 3*10^47)
unit MRNG;
interface
function MRandom:Double;
function MRandInt(Low,High:Integer):Integer;
procedure MRandSeed(Seed:Integer);
implementation
var
M0 :Integer = 0;
M1 :Integer = 0;
M2 :Integer = 0;
M3 :Integer = 0;
MC :Integer = 0;
MF3 :Integer = 2111111111;
MF2 :Integer = 1492;
MF1 :Integer = 1776;
MF0 :Integer = 5115;
F2M32 :Integer = $2F800000;
EXTEND:Comp = 0;
function MRandom:Double;
{Generate random decimal in the range [0..1]}
asm
PUSH EDI
MOV EAX, MF3
MUL M3
MOV ECX,EAX
MOV EAX, M2
MOV EDI,EDX
MOV M3, EAX
MUL MF2
ADD ECX,EAX
MOV EAX, M1
ADC EDI,EDX
MOV M2,EAX
MUL MF1
ADD ECX,EAX
MOV EAX,M0
ADC EDI,EDX
MOV M1,EAX
MUL MF0
ADD EAX,ECX
ADC EDX,EDI
ADD EAX,MC
ADC EDX,0
MOV M0,EAX
MOV MC,EDX
LEA EDI,EXTEND
MOV [EDI],EAX
FILD EXTEND
POP EDI
FMUL F2M32
end;
procedure MRandSeed(Seed:Integer);
{Initialize generator; use Seed := GetTickCount to initialize from system clock}
asm
PUSH EDI
CMP EAX, 1
SBB EAX, 0
XOR ECX, ECX
@R80:
MOV EDX, EAX
SHL EAX, 13
XOR EDX, EAX
MOV EAX, EDX
SHR EDX, 17
XOR EAX, EDX
MOV EDX, EAX
SHL EDX, 5
XOR EAX, EDX
MOV M0[ECX*4], EAX
INC ECX
CMP ECX, 5
JB @R80
MOV EDI, 19
@R90:
CALL MRandom
FSTP ST(0)
DEC EDI
JNZ @R90
POP EDI
end;
function MRandInt(Low,High:Integer):Integer;
{Generate random integer in the range [Low..High]}
begin
Result := Low + Trunc(MRandom*(High-Low));
end;
end.