[net.sources] 2 Random Number Generators

spaf@gatech.UUCP (06/13/83)

I've seen a few requests recently for random number generators.
The following code shows how to implement a very good pseudo-
random generator.  Unfortunately, someone will have to code
it into assembler since it will not run as a Pascal routine.
The generator expects the variable "temp" to be 63 or 64 bits
wide for after the multiplication in the first assignment;
a clever programmer will note that the 2nd and 3rd steps
can be done at the same time with proper register fiddling
after the multiplication.

I don't know any PDP assembly or I'd code it up myself.

If you want a version you can run from Pascal, try the second
algorithm.  It's not quite as good as the first, but it
should do for many applications.

Cheers.
-----------

{The following function returns a floating point value
 randomly distributed between 0.0 and 1.0 (open interval).
 The parameter "seed" is modified to be an integer between
 1 and 2147483647 (closed interval).

 The alogrithm and multiplier values are taken from the article
 "A Statistical Evaluation of Multiplicative Congruential Random
  Number Generators with Modulus 2^31 - 1" by George S. Fishman
  and Louis R. Moore.  The article was published in the Journal
  of the American Statistical Association, March 1982, Vol 77, #377
  pp. 129-136. }

CONST
   multiplier = 764261123;
   two_to_31 = 2147483648;

FUNCTION random (VAR seed: INTEGER) : REAL;
VAR
   temp, temp2 : INTEGER;
BEGIN
   temp := seed * multiplier;
   temp2 := temp DIV two_to_31;
   seed := temp - temp2 * two_to_31;
   seed := seed + temp2;
   temp2 := seed DIV two_to_31;
   IF (temp2 <> 0) THEN
      seed := seed - (two_to_31 - 1);
   random := seed / two_to_31
END;

----------------
Second algorithm:

{This is taken from "Software Manual for the Elementary Functions"
 by William J. Cody, Jr. and William Waite, Prentice Hall, 1980.
 They based it on algorithm 266 by Pike and Hill (modified by Hansson),
 presented in CACM, vol. 8, #10, Oct. 1965.

 The function returns a real value between 0.0 and 1.0, and
 the parameter gets set to an integer between 1 and 2796203.}

CONST
   multiplier = 2796203;

FUNCTION random (VAR seed : INTEGER) : REAL;
BEGIN
   seed := seed * 125;
   seed := seed - (seed DIV multiplier) * multiplier;
   random := seed / multiplier
END;

---------
-- 
"The soapbox of Gene Spafford"

Spaf @ GATech		        (CS Net)
Spaf.GATech @ UDel-Relay        (ARPA)		 School of ICS
...!{sb1, allegra}!gatech!spaf  (uucp)      	 Georgia Tech
...!duke!mcnc!msdc!gatech!spaf                   Atlanta, GA 30332