mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Fix random number generator on 64-bit platforms
* libguile/random.c (scm_c_random): On platforms where `unsigned long' has 64 bit, generate up to 64 bit of randomness. This is expected by scm_c_random_bignum(), and hence was a serious distortion of the random value distribution for values exceeding 2^32. This change also fixes a crash when the `m' argument is a value above 2^32.
This commit is contained in:
parent
d68a81e038
commit
442eaa681b
1 changed files with 27 additions and 1 deletions
|
@ -223,7 +223,8 @@ unsigned char scm_masktab[256];
|
|||
unsigned long
|
||||
scm_c_random (scm_t_rstate *state, unsigned long m)
|
||||
{
|
||||
unsigned int r, mask;
|
||||
unsigned long r, mask;
|
||||
#if SCM_SIZEOF_UNSIGNED_LONG == 4
|
||||
mask = (m < 0x100
|
||||
? scm_masktab[m]
|
||||
: (m < 0x10000
|
||||
|
@ -232,6 +233,31 @@ scm_c_random (scm_t_rstate *state, unsigned long m)
|
|||
? scm_masktab[m >> 16] << 16 | 0xffff
|
||||
: scm_masktab[m >> 24] << 24 | 0xffffff)));
|
||||
while ((r = scm_the_rng.random_bits (state) & mask) >= m);
|
||||
#elif SCM_SIZEOF_UNSIGNED_LONG == 8
|
||||
mask = (m < 0x100
|
||||
? scm_masktab[m]
|
||||
: (m < 0x10000
|
||||
? scm_masktab[m >> 8] << 8 | 0xff
|
||||
: (m < 0x1000000
|
||||
? scm_masktab[m >> 16] << 16 | 0xffff
|
||||
: (m < (1UL << 32)
|
||||
? scm_masktab[m >> 24] << 24 | 0xffffff
|
||||
: (m < (1UL << 40)
|
||||
? ((unsigned long) scm_masktab[m >> 32] << 32
|
||||
| 0xffffffffUL)
|
||||
: (m < (1UL << 48)
|
||||
? ((unsigned long) scm_masktab[m >> 40] << 40
|
||||
| 0xffffffffffUL)
|
||||
: (m < (1UL << 56)
|
||||
? ((unsigned long) scm_masktab[m >> 48] << 48
|
||||
| 0xffffffffffffUL)
|
||||
: ((unsigned long) scm_masktab[m >> 56] << 56
|
||||
| 0xffffffffffffffUL))))))));
|
||||
while ((r = ((scm_the_rng.random_bits (state) << 32
|
||||
| scm_the_rng.random_bits (state))) & mask) >= m);
|
||||
#else
|
||||
#error "Cannot deal with this platform's unsigned long size"
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue