From 9defb64118774c8f1a1f6af05d6f1705e7a40619 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Tue, 27 Jul 2010 11:32:31 +0200 Subject: [PATCH] 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. --- libguile/random.c | 23 ++++++++++++++++++++--- libguile/random.h | 2 +- 2 files changed, 21 insertions(+), 4 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)) diff --git a/libguile/random.h b/libguile/random.h index 51b9a0c1a..512b7d259 100644 --- a/libguile/random.h +++ b/libguile/random.h @@ -40,7 +40,7 @@ typedef struct scm_t_rstate { struct scm_t_rng *rng; - double normal_next; /* For scm_c_uniform01 */ + double normal_next; /* For scm_c_normal01 */ /* Custom fields follow here */ } scm_t_rstate; -- 2.20.1