diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/fns.c | 28 |
1 files changed, 17 insertions, 11 deletions
| @@ -64,17 +64,23 @@ With argument t, set the random number seed from the current time and pid.") | |||
| 64 | srandom (getpid () + time (0)); | 64 | srandom (getpid () + time (0)); |
| 65 | if (XTYPE (limit) == Lisp_Int && XINT (limit) > 0) | 65 | if (XTYPE (limit) == Lisp_Int && XINT (limit) > 0) |
| 66 | { | 66 | { |
| 67 | /* Try to take our random number from the higher bits of VAL, | 67 | if (XINT (limit) >= 0x40000000) |
| 68 | not the lower, since (says Gentzel) the low bits of `random' | 68 | /* This case may occur on 64-bit machines. */ |
| 69 | are less random than the higher ones. We do this by using the | 69 | val = random () % XINT (limit); |
| 70 | quotient rather than the remainder. At the high end of the RNG | 70 | else |
| 71 | it's possible to get a quotient larger than limit; discarding | 71 | { |
| 72 | these values eliminates the bias that would otherwise appear | 72 | /* Try to take our random number from the higher bits of VAL, |
| 73 | when using a large limit. */ | 73 | not the lower, since (says Gentzel) the low bits of `random' |
| 74 | denominator = (unsigned long)0x40000000 / XFASTINT (limit); | 74 | are less random than the higher ones. We do this by using the |
| 75 | do | 75 | quotient rather than the remainder. At the high end of the RNG |
| 76 | val = (random () & 0x3fffffff) / denominator; | 76 | it's possible to get a quotient larger than limit; discarding |
| 77 | while (val >= limit); | 77 | these values eliminates the bias that would otherwise appear |
| 78 | when using a large limit. */ | ||
| 79 | denominator = (unsigned long)0x40000000 / XFASTINT (limit); | ||
| 80 | do | ||
| 81 | val = (random () & 0x3fffffff) / denominator; | ||
| 82 | while (val >= limit); | ||
| 83 | } | ||
| 78 | } | 84 | } |
| 79 | else | 85 | else |
| 80 | val = random (); | 86 | val = random (); |