/ circle3.1 / src / random.c
random.c
 1  /* ************************************************************************
 2  *   File: random.c                                      Part of CircleMUD *
 3  *  Usage: pseudo-random number generator                                  *
 4  ************************************************************************ */
 5  
 6  /*
 7   * I am bothered by the non-portablility of 'rand' and 'random' -- rand
 8   * is ANSI C, but on some systems such as Suns, rand has seriously tragic
 9   * spectral properties (the low bit alternates between 0 and 1!).  random
10   * is better but isn't supported by all systems.  So, in my quest for Ultimate
11   * CircleMUD Portability, I decided to include this code for a simple but
12   * relatively effective random number generator.  It's not the best RNG code
13   * around, but I like it because it's very short and simple, and for our
14   * purposes it's "random enough".
15   *               --Jeremy Elson  2/23/95
16   *
17   * Now that we're using GNU's autoconf, I've coded Circle to always use
18   * random(), and automatically link in this object file if random() isn't
19   * supported on the target system.  -JE 2/3/96
20   *
21   * Well, despite autoconf we're back to using this random all the
22   * time.  Oh well, there's no harm in changing my mind on this one
23   * from release to release...  -JE 10/28/97
24   */
25  
26  /***************************************************************************/
27  
28  /*
29   *
30   * This program is public domain and was written by William S. England
31   * (Oct 1988).  It is based on an article by:
32   *
33   * Stephen K. Park and Keith W. Miller. RANDOM NUMBER GENERATORS:
34   * GOOD ONES ARE HARD TO FIND. Communications of the ACM,
35   * New York, NY.,October 1988 p.1192
36  
37   The following is a portable c program for generating random numbers.
38   The modulus and multipilier have been extensively tested and should
39   not be changed except by someone who is a professional Lehmer generator
40   writer.  THIS GENERATOR REPRESENTS THE MINIMUM STANDARD AGAINST WHICH
41   OTHER GENERATORS SHOULD BE JUDGED. ("Quote from the referenced article's
42   authors. WSE" )
43  */
44  
45  #define	m  (unsigned long)2147483647
46  #define	q  (unsigned long)127773
47  
48  #define	a (unsigned int)16807
49  #define	r (unsigned int)2836
50  
51  /*
52  ** F(z)	= (az)%m
53  **	= az-m(az/m)
54  **
55  ** F(z)  = G(z)+mT(z)
56  ** G(z)  = a(z%q)- r(z/q)
57  ** T(z)  = (z/q) - (az/m)
58  **
59  ** F(z)  = a(z%q)- rz/q+ m((z/q) - a(z/m))
60  ** 	 = a(z%q)- rz/q+ m(z/q) - az
61  */
62  
63  static unsigned long seed;
64  
65  /* local functions */
66  void circle_srandom(unsigned long initial_seed);
67  unsigned long circle_random(void);
68  
69  
70  void circle_srandom(unsigned long initial_seed)
71  {
72      seed = initial_seed; 
73  }
74  
75  
76  unsigned long circle_random(void)
77  {
78     int lo, hi, test;
79  
80      hi   = seed/q;
81      lo   = seed%q;
82  
83      test = a*lo - r*hi;
84  
85      if (test > 0)
86  	seed = test;
87      else
88  	seed = test+ m;
89  
90      return (seed);
91  }