csrobe@ICASE.EDU (Charles S. [Chip] Roberson) (03/17/89)
Here are 2 code fragments for an excellent Random Number generator written
by Dr. Steve Park of William and Mary. For more information, see
"Random Number Generators: Good Ones are Hard to Find", in the October
1988 issue of _Communications_of_The_ACM_.
s : integer; { stream index }
seed : array [0..255] of real;
{* This file should be used on systems that only have 16-bit integers *}
function Random : real;
const
a = 16807.0;
m = 2147483647.0;
q = 127773.0; { m div a }
r = 2836.0; { m mod a }
var
lo, hi, test : real;
begin
if (s > 0) then
begin
hi := trunc(seed[s] / q);
lo := seed[s] - q * hi;
test := a * lo - r * hi;
if test > 0.0 then
seed[s] := test
else
seed[s] := test + m;
Random := seed[s] / m
end
else
Random := 0.5
end; { Random }
procedure Plant_Seeds; { a private procedure which is }
const { used to "plant" a sequence of }
a = 8350.0; { seeds seperated one from the }
m = 2147483647.0; { next by 8,016,548 steps }
q = 257183.0; { m div a }
r = 5597.0; { m mod a }
var
j : integer;
lo, hi, test : real;
begin
for j := 2 to 255 do
begin
hi := trunc(seed[j - 1] / q);
lo := seed[j - 1] - q * hi;
test := a * lo - r * hi;
if test > 0.0 then
seed[j] := test
else
seed[j] := test + m
end
end; { Plant_Seeds }
{*}
procedure Randomize;
var
t : integer; { 32-bit 2's compliment integer }
begin
repeat
writeln;
write('Enter a positive integer seed (9 digits or less) >> ');
readln(t)
until (0 < t) and (t < 2147483647);
writeln;
seed[1] := t; { this is seed[1] - now }
Plant_Seeds { plant the other seeds }
end; { Randomize }
procedure Select_Stream(stream : integer);
begin
s := stream
end; { Select_Stream }
{ end implementation }
procedure init_rngs;
begin { initialize }
s := 1; { supply a default stream }
seed[s] := 123456789.0; { and an initial seed }
Plant_Seeds
end; { end initialize }
--------------------------------------------------------------------------
s : integer; { stream index }
seed : array [0..255] of integer;
{* This file should be used on systems that has 32-bit integers or larger *}
function Random : real;
const
a = 16807;
m = 2147483647;
q = 127773; { m div a }
r = 2836; { m mod a }
var
lo, hi, test : integer;
begin
if (s > 0) then
begin
hi := trunc(seed[s] / q);
lo := seed[s] - q * hi;
test := a * lo - r * hi;
if test > 0.0 then
seed[s] := test
else
seed[s] := test + m;
Random := seed[s] / m
end
else
Random := 0.5
end; { Random }
procedure Plant_Seeds; { a private procedure which is }
const { used to "plant" a sequence of }
a = 8350; { seeds seperated one from the }
m = 2147483647; { next by 8,016,548 steps }
q = 257183; { m div a }
r = 5597; { m mod a }
var
j : integer;
lo, hi, test : integer;
begin
for j := 2 to 255 do
begin
hi := trunc(seed[j - 1] / q);
lo := seed[j - 1] - q * hi;
test := a * lo - r * hi;
if test > 0.0 then
seed[j] := test
else
seed[j] := test + m
end
end; { Plant_Seeds }
{*}
procedure Randomize;
var
t : integer; { 32-bit 2's compliment integer }
begin
repeat
writeln;
write('Enter a positive integer seed (9 digits or less) >> ');
readln(t)
until (0 < t) and (t < 2147483647);
writeln;
seed[1] := t; { this is seed[1] - now }
Plant_Seeds { plant the other seeds }
end; { Randomize }
procedure Select_Stream(stream : integer);
begin
s := stream
end; { Select_Stream }
{ end implementation }
procedure init_rngs;
begin { initialize }
s := 1; { supply a default stream }
seed[s] := 123456789; { and an initial seed }
Plant_Seeds
end; { end initialize }
--------------------------------------------------------------------------
I know that this generator works under OSS Personal Pascal, because I've
used it.
Enjoy,
-c
|Chip Roberson ARPANET: csrobe@cs.wm.edu |
|Dept of Comp. Sci. csrobe@icase.edu |
|College of William and Mary BITNET: #csrobe@wmmvs.bitnet |
|Williamsburg, VA 23185 UUCP: ...!uunet!pyrdc!gmu90x!wmcs!csrobe|
"It takes 40 dumb animals to make a fur coat,
and just one dumb animal to wear it." -European TV commercial
[A Cruelty-Free Companies list is available for anonymous ftp from cs.wm.edu.]