From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 25-APR-1994 16:25:31.33
To:	EVERHART
CC:	
Subj:	Re: DCL random number

X-Newsgroups: comp.os.vms
From: eric@HQ.Ileaf.COM (Eric Sosman x4425)
Subject: Re: DCL random number
Message-ID: <Cottxp.HJ6@HQ.Ileaf.COM>
Summary: Minimal Standard Random Number Generator in DCL
Sender: usenet@HQ.Ileaf.COM
Nntp-Posting-Host: natasha
Organization: Interleaf, Inc.
Date: Mon, 25 Apr 1994 17:58:37 GMT
Lines: 72
To: Info-VAX@CRVAX.SRI.COM
X-Gateway-Source-Info: USENET

    If you need *a* "random" number in DCL, it usually suffices to grab
a few digits from the system time.  If you need more than one "random"
number, just consulting the clock isn't a very good idea.  Here's a four-
line solution embedded in a 63-line package (for efficiency's sake).

$! MSRAND.COM -- Minimal Standard Random Number Generator
$!
$! This is a DCL implementation of the "Minimal Standard Random Number
$! Generator" described in "Random number generators: good ones are hard
$! to find" by Stephen K. Park and Keith W. Miller, Communications of the
$! ACM Volume 31 Number 10 (October 1988), pages 1192-1201.
$!
$! USAGE:
$!
$! Initialize by setting the global symbol MSRANDVAL to any integer in
$! the range 1 <= MSRANDVAL <= 2147483646.  If you don't initialize
$! MSRANDVAL or initialize it improperly, this procedure initializes
$! it to 1.
$!
$! Thereafter, call this procedure each time you need a "random" number.
$! It uses Park & Miller's method to assign a new value to MSRANDVAL,
$! still in the range 1 <= MSRANDVAL <= 2147483646.
$!
$! HINTS:
$!
$! [1] A reasonable way to initialize MSRANDVAL is to put something like
$! this in your LOGIN.COM file:
$!      $ time = f$cvtime(,,"time") - ":" - ":" - "."
$!      $ msrandval == f$integer(time)	! *two* equal signs
$!
$! [2] Unlike the values produced by many other random number generators,
$! the low-order bits of MSRANDVAL are "as random as" the high-order bits
$! (see Park & Miller's article for a more precise statement).
$!
$! [3] "I'm just trying to choose one of twelve fortune cookies.  What am
$! I supposed to do with two billion possible MSRANDVAL values?"
$!      $ @msrand
$!      $ cookie = msrandval - msrandval / 12 * 12
$!	$! cookie now holds a "random" integer, 0 <= cookie <= 11
$!
$! [4] To satisfy yourself that this implementation is correct, apply Park &
$! Miller's verification procedure: initialize MSRANDVAL to 1, call this
$! procedure exactly ten thousand times, and inspect the final value of
$! MSRANDVAL.  If all goes well, it will be 1043618065.
$!
$! [5] If you're going to be generating a significant quantity of random
$! numbers you may be tempted to strip out all the comments and sanity-
$! checking for greater speed.  Go ahead, if you must, but I've got a
$! better idea: write your program in something other than DCL (you can
$! use the same algorithm and test it the same way).
$!
$! HISTORY:
$!  22-Apr-1994 (Eric Sosman): Translated C implementation to DCL.
$!  19-Feb-1993 (Eric Sosman): Translated Park & Miller's "Integer Version II"
$!	from pseudocode to C.
$!=============================================================================
$!
$! Sanity-checking:
$!
$   if f$type(msrandval) .nes. "INTEGER" then msrandval == 1
$   if msrandval .lt. 1 .or. msrandval .gt. 2147483646 then msrandval == 1
$!
$! Park & Miller's computation (the numbers are "magical;" see the article):
$!
$   quot = msrandval / 127773
$   rmdr = msrandval - quot * 127773
$   msrandval == 16807 * rmdr - 2836 * quot
$   if msrandval .lt. 0 then msrandval == msrandval + 2147483647

----
Eric Sosman             Interleaf, Inc. / Prospect Place
eric@ileaf.com          9 Hillside Ave. / Waltham, MA 02154 (USA)

