diff options
author | Andy Wingo <wingo@pobox.com> | 2010-07-27 11:32:31 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2010-07-27 11:32:40 +0200 |
commit | 9defb64118774c8f1a1f6af05d6f1705e7a40619 (patch) | |
tree | 6cf4f1da300926e7414d9a0da25918bfbecfeb2c /libguile/random.c | |
parent | 17fc9efecbc9cb0c7e32664dbd0e2c863194cd7f (diff) | |
download | guile-9defb64118774c8f1a1f6af05d6f1705e7a40619.tar.gz |
64-bit random fixes
* libguile/random.c (scm_random): Fix generation of inum randoms with
more than 32 bits.
* libguile/random.h (scm_t_rstate): Fix a comment.
Diffstat (limited to 'libguile/random.c')
-rw-r--r-- | libguile/random.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/libguile/random.c b/libguile/random.c index 6703dac22..83870f6ad 100644 --- a/libguile/random.c +++ b/libguile/random.c @@ -371,9 +371,26 @@ SCM_DEFINE (scm_random, "random", 1, 1, 0, SCM_VALIDATE_RSTATE (2, state); if (SCM_I_INUMP (n)) { - scm_t_uint32 m = SCM_I_INUM (n); - SCM_ASSERT_RANGE (1, n, m > 0); - return scm_from_uint32 (scm_c_random (SCM_RSTATE (state), m)); + unsigned long m = (unsigned long) SCM_I_INUM (n); + SCM_ASSERT_RANGE (1, n, SCM_I_INUM (n) > 0); +#if SCM_SIZEOF_UNSIGNED_LONG <= 4 + return scm_from_uint32 (scm_c_random (SCM_RSTATE (state), + (scm_t_uint32) m)); +#elif SCM_SIZEOF_UNSIGNED_LONG <= 8 + if (m <= SCM_T_UINT32_MAX) + return scm_from_uint32 (scm_c_random (SCM_RSTATE (state), + (scm_t_uint32) m)); + else + { + scm_t_uint64 upper, lower; + + upper = scm_c_random (SCM_RSTATE (state), (scm_t_uint32) (m >> 32)); + lower = scm_c_random (SCM_RSTATE (state), SCM_T_UINT32_MAX); + return scm_from_uint64 ((upper << 32) | lower); + } +#else +#error "Cannot deal with this platform's unsigned long size" +#endif } SCM_VALIDATE_NIM (1, n); if (SCM_REALP (n)) |