author | Alpar Juttner <alpar@cs.elte.hu> |
Sun, 11 Dec 2011 11:19:39 +0100 | |
changeset 11 | cf6519daa7fa |
permissions | -rw-r--r-- |
alpar@6 | 1 |
/*** This is a portable random number generator whose origins are |
alpar@6 | 2 |
*** unknown. As far as can be told, this is public domain software. |
alpar@6 | 3 |
|
alpar@6 | 4 |
|
alpar@6 | 5 |
/*** portable random number generator */ |
alpar@6 | 6 |
|
alpar@6 | 7 |
/*** Note that every variable used here must have at least 31 bits |
alpar@6 | 8 |
*** of precision, exclusive of sign. Long integers should be enough. |
alpar@6 | 9 |
*** The generator is the congruential: i = 7**5 * i mod (2^31-1). |
alpar@6 | 10 |
***/ |
alpar@6 | 11 |
|
alpar@6 | 12 |
#define MULTIPLIER 16807 |
alpar@6 | 13 |
#define MODULUS 2147483647 |
alpar@6 | 14 |
|
alpar@6 | 15 |
static long saved_seed; |
alpar@6 | 16 |
|
alpar@6 | 17 |
|
alpar@6 | 18 |
/*** set_random - initialize constants and seed */ |
alpar@6 | 19 |
|
alpar@6 | 20 |
void set_random(seed) |
alpar@6 | 21 |
long seed; |
alpar@6 | 22 |
{ |
alpar@6 | 23 |
saved_seed = seed; |
alpar@6 | 24 |
} |
alpar@6 | 25 |
|
alpar@6 | 26 |
|
alpar@6 | 27 |
/*** ng_random - generate a random integer in the interval [a,b] (b >= a >= 0) */ |
alpar@6 | 28 |
|
alpar@6 | 29 |
long ng_random(a, b) |
alpar@6 | 30 |
long a, b; |
alpar@6 | 31 |
{ |
alpar@6 | 32 |
register long hi, lo; |
alpar@6 | 33 |
|
alpar@6 | 34 |
hi = MULTIPLIER * (saved_seed >> 16); |
alpar@6 | 35 |
lo = MULTIPLIER * (saved_seed & 0xffff); |
alpar@6 | 36 |
hi += (lo>>16); |
alpar@6 | 37 |
lo &= 0xffff; |
alpar@6 | 38 |
lo += (hi>>15); |
alpar@6 | 39 |
hi &= 0x7fff; |
alpar@6 | 40 |
lo -= MODULUS; |
alpar@6 | 41 |
if ((saved_seed = (hi<<16) + lo) < 0) |
alpar@6 | 42 |
saved_seed += MODULUS; |
alpar@6 | 43 |
|
alpar@6 | 44 |
if (b <= a) |
alpar@6 | 45 |
return b; |
alpar@6 | 46 |
return a + saved_seed % (b - a + 1); |
alpar@6 | 47 |
} |