From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/rg_rand.c | 88 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/rg_rand.c (limited to 'reference/C/CONTRIB/SNIP/rg_rand.c') diff --git a/reference/C/CONTRIB/SNIP/rg_rand.c b/reference/C/CONTRIB/SNIP/rg_rand.c new file mode 100755 index 0000000..578f70a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_rand.c @@ -0,0 +1,88 @@ +/* +** longrand() -- generate 2**31-2 random numbers +** +** public domain by Ray Gardner +** +** based on "Random Number Generators: Good Ones Are Hard to Find", +** S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), +** and "Two Fast Implementations of the 'Minimal Standard' Random +** Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), p. 87-88 +** +** linear congruential generator f(z) = 16807 z mod (2 ** 31 - 1) +** +** uses L. Schrage's method to avoid overflow problems +*/ + +#define a 16807 /* multiplier */ +#define m 2147483647L /* 2**31 - 1 */ +#define q 127773L /* m div a */ +#define r 2836 /* m mod a */ + +long nextlongrand(long seed) +{ + unsigned long lo, hi; + + lo = a * (long)(seed & 0xFFFF); + hi = a * (long)((unsigned long)seed >> 16); + lo += (hi & 0x7FFF) << 16; + if (lo > m) + { + lo &= m; + ++lo; + } + lo += hi >> 15; + if (lo > m) + { + lo &= m; + ++lo; + } + return (long)lo; +} + +static long randomnum = 1; + +long longrand(void) /* return next random long */ +{ + randomnum = nextlongrand(randomnum); + return randomnum; +} + +void slongrand(unsigned long seed) /* to seed it */ +{ + randomnum = seed ? (seed & m) : 1; /* nonzero seed */ +} + + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + long reps, k, num; + unsigned long seed; + + reps = 10000; + seed = 1; + + /* + ** correctness test: after 10000 reps starting with seed 1, + ** result should be 1043618065 + */ + + if (argc > 1) + reps = atol(argv[1]); + if (argc > 2) + seed = atol(argv[2]); + + printf("seed %ld for %ld reps...\n", seed, reps); + slongrand(seed); + for (k = 0; k < reps; ++k) + num = longrand(); + printf("%ld\n", num); + + return 0; +} + +#endif -- cgit v1.2.3-54-g00ecf