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.]