wmud/old-codebase/src/random.c

92 lines
2.7 KiB
C

/* ************************************************************************
* File: random.c Part of CircleMUD *
* Usage: pseudo-random number generator *
************************************************************************ */
/*
* I am bothered by the non-portablility of 'rand' and 'random' -- rand
* is ANSI C, but on some systems such as Suns, rand has seriously tragic
* spectral properties (the low bit alternates between 0 and 1!). random
* is better but isn't supported by all systems. So, in my quest for Ultimate
* CircleMUD Portability, I decided to include this code for a simple but
* relatively effective random number generator. It's not the best RNG code
* around, but I like it because it's very short and simple, and for our
* purposes it's "random enough".
* --Jeremy Elson 2/23/95
*
* Now that we're using GNU's autoconf, I've coded Circle to always use
* random(), and automatically link in this object file if random() isn't
* supported on the target system. -JE 2/3/96
*
* Well, despite autoconf we're back to using this random all the
* time. Oh well, there's no harm in changing my mind on this one
* from release to release... -JE 10/28/97
*/
/***************************************************************************/
/*
*
* This program is public domain and was written by William S. England
* (Oct 1988). It is based on an article by:
*
* Stephen K. Park and Keith W. Miller. RANDOM NUMBER GENERATORS:
* GOOD ONES ARE HARD TO FIND. Communications of the ACM,
* New York, NY.,October 1988 p.1192
The following is a portable c program for generating random numbers.
The modulus and multipilier have been extensively tested and should
not be changed except by someone who is a professional Lehmer generator
writer. THIS GENERATOR REPRESENTS THE MINIMUM STANDARD AGAINST WHICH
OTHER GENERATORS SHOULD BE JUDGED. ("Quote from the referenced article's
authors. WSE" )
*/
#define m (unsigned long)2147483647
#define q (unsigned long)127773
#define a (unsigned int)16807
#define r (unsigned int)2836
/*
** F(z) = (az)%m
** = az-m(az/m)
**
** F(z) = G(z)+mT(z)
** G(z) = a(z%q)- r(z/q)
** T(z) = (z/q) - (az/m)
**
** F(z) = a(z%q)- rz/q+ m((z/q) - a(z/m))
** = a(z%q)- rz/q+ m(z/q) - az
*/
static unsigned long seed;
/* local functions */
void circle_srandom(unsigned long initial_seed);
unsigned long circle_random(void);
void circle_srandom(unsigned long initial_seed)
{
seed = initial_seed;
}
unsigned long circle_random(void)
{
int lo, hi, test;
hi = seed/q;
lo = seed%q;
test = a*lo - r*hi;
if (test > 0)
seed = test;
else
seed = test+ m;
return (seed);
}