From mcmahon@metalab.unc.eduWed May  3 22:06:24 2000
Date: Wed, 3 May 2000 13:26:48 -0400 (EDT)
From: Joe McMahon <mcmahon@metalab.unc.edu>
To: petrich@netcom.com
Newsgroups: alt.games.marathon
Subject: Re: Aleph One 0.10.1 Released

Some very short, fast, and small RNGs from Dr. George Marsaglia, a well-known
authority on random numbers. I've used a couple of these and they are 
small, cheap, and fast.

#define znew  (z=36969*(z&65535)+(z>>16))
#define wnew  (w=18000*(w&65535)+(w>>16))
#define MWC   ( (znew<<16)+wnew )
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
#define CONG  (jcong=69069*jcong+1234567)
#define KISS  ((MWC^CONG)+SHR3)
#define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+178],t[++c])
#define SWB   (t[c+237]=(x=t[c+15])-(y=t[c]+(x<y)),t[++c])
#define UNI   (KISS*2.328306e-10)
#define VNI   ((long) KISS)*4.656613e-10
typedef unsigned long UL;

/*  Global static variables: */
 static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160;
 static UL t[256];
 static UL x=0,y=0; static unsigned char c=0;
/* Random seeds must be used to reset z,w,jsr,jcong and
the table t[256].  Here is an example procedure, using KISS: */

 void settable(UL i1,UL i2,UL i3,UL i4)
 { int i; z=i1;w=i2,jsr=i3; jcong=i4;
 for(i=0;i<256;i++)  t[i]=KISS;        }

/* Any one of KISS, MWC, LFIB4, SWB, SHR3, or CONG  can be used in
   an expression to provide a random 32-bit integer, while UNI
   provides a real in (0,1) and VNI a real in (-1,1).   */

And a quote.

 "All combinations seem to support the supplemented quote
  from my 1984 Keynote Address:

       A random number generator is like sex;
       When it's good, it's wonderful,
       And when it's bad, it's still pretty good.

       And when it's bad, try a twosome or threesome."

Many more details at http://www.io.com/~ritter/NEWS4/RANDC.HTM. He gives 
specifics - KISS has a period of 2^123, MWC 2^60, SHR3 2^32-1, KISS+LFIB4
is 2^410, SWB is 2^7578 (and VERY fast). 

Timing to generate 100,000,000 random numbers in a tight loop (in 
nanoseconds, on a (ptui) Pentium 300MHz): LFIB4=64; CONG=90; SWB=100; 
SHR3=110; KISS=209; KISS+LFIB4=252; KISS+SWB=310

Thanks for the work; I'm glad to have the change to give something (minor) back.

 --- Joe M.
