code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
Terms of Agreement:
By using this code, you agree to the following terms...
1) You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for langauges that allow it) freely and with no charge.
2) You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this code from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
/* +++Date last modified: 05-Jul-1997 */
/*
** 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 /* TEST */