From cfbccaf49ca248a1c6076a21c063e5b2e925dbea Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Tue, 27 Jul 2010 11:43:22 +0200 Subject: [PATCH] scm_random fix for 64-bit inums * libguile/random.c (scm_random): Fix for 64-bit inums. --- libguile/random.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/libguile/random.c b/libguile/random.c index e150fb4dc..1c2f668d0 100644 --- a/libguile/random.c +++ b/libguile/random.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999,2000,2001, 2003, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001, 2003, 2005, 2006, 2010 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -315,9 +315,26 @@ SCM_DEFINE (scm_random, "random", 1, 1, 0, SCM_VALIDATE_RSTATE (2, state); if (SCM_I_INUMP (n)) { - unsigned long m = SCM_I_INUM (n); - SCM_ASSERT_RANGE (1, n, m > 0); - return scm_from_ulong (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))