1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
{ ******************************************************************
Random number generators
****************************************************************** }
unit urandom;
interface
uses
utypes, uranmwc, uranmt, uranuvag;
procedure SetRNG(RNG : RNG_Type);
{ Select generator and set default initialization }
procedure InitGen(Seed : LongInt);
{ Initialize generator }
function IRanGen : LongInt;
{ 32-bit random integer in [-2^31 .. 2^31 - 1] }
function IRanGen31 : LongInt;
{ 31-bit random integer in [0 .. 2^31 - 1] }
function RanGen1 : Float;
{ 32-bit random real in [0,1] }
function RanGen2 : Float;
{ 32-bit random real in [0,1) }
function RanGen3 : Float;
{ 32-bit random real in (0,1) }
function RanGen53 : Float;
{ 53-bit random real in [0,1) }
implementation
const
Z = 1.0 / 4294967296.0; { 1 / 2^32 }
Z1 = 1.0 / 4294967295.0; { 1 / (2^32 - 1) }
Z2 = 1.0 / 9007199254740992.0;
var
gRNG : RNG_Type;
procedure SetRNG(RNG : RNG_Type);
var
InitMT : MTKeyArray;
begin
gRNG := RNG;
case gRNG of
RNG_MWC : InitMWC(118105245);
RNG_MT : begin
InitMT[0] := $123;
InitMT[1] := $234;
InitMT[2] := $345;
InitMT[3] := $456;
InitMTbyArray(InitMT, 4);
end;
RNG_UVAG : InitUVAGbyString('abcd');
end;
end;
procedure InitGen(Seed : LongInt);
begin
case gRNG of
RNG_MWC : InitMWC(Seed);
RNG_MT : InitMT(Seed);
RNG_UVAG : InitUVAG(Seed);
end;
end;
function IRanGen : LongInt;
begin
case gRNG of
RNG_MWC : IRanGen := IRanMWC;
RNG_MT : IRanGen := IRanMT;
RNG_UVAG : IRanGen := IRanUVAG;
end;
end;
function IRanGen31 : LongInt;
begin
IRanGen31 := IRanGen shr 1;
end;
function RanGen1 : Float;
begin
RanGen1 := (IRanGen + 2147483648.0) * Z1
end;
function RanGen2 : Float;
begin
RanGen2 := (IRanGen + 2147483648.0) * Z
end;
function RanGen3 : Float;
begin
RanGen3 := (IRanGen + 2147483648.5) * Z
end;
function RanGen53 : Float;
var
A, B : LongInt;
begin
A := IRanGen shr 5;
B := IRanGen shr 6;
RanGen53 := (A * 67108864.0 + B) * Z2;
end;
end.
|