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