From b4fb077fef0d554ece144d27070d176957f09087 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Mon, 13 Jul 2020 10:27:04 +0900 Subject: [PATCH] random_r doesn't necessarily provide enough bits even for a fixnum (issue #668) --- lib/srfi/27/rand.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/srfi/27/rand.c b/lib/srfi/27/rand.c index 8946f176..be286c57 100644 --- a/lib/srfi/27/rand.c +++ b/lib/srfi/27/rand.c @@ -55,7 +55,8 @@ typedef unsigned int sexp_random_t; sexp sexp_rs_random_integer (sexp ctx, sexp self, sexp_sint_t n, sexp rs, sexp bound) { sexp res; - sexp_int32_t m; + int64_t m; + sexp_int32_t m2; #if SEXP_USE_BIGNUMS sexp_uint_t mod; sexp_uint32_t *data; @@ -67,7 +68,11 @@ sexp sexp_rs_random_integer (sexp ctx, sexp self, sexp_sint_t n, sexp rs, sexp b if (sexp_unbox_fixnum(bound) <= 0) { res = sexp_xtype_exception(ctx, self, "random bound must be positive", bound); } else { - sexp_call_random(rs, m); + /* ensure we have sufficient bits */ + for (i=m=0; i <= 1<<(CHAR_BIT*sizeof(m))/RAND_MAX; ++i) { + sexp_call_random(rs, m2); + m = m * RAND_MAX + m2; + } res = sexp_make_fixnum(m % sexp_unbox_fixnum(bound)); } #if SEXP_USE_BIGNUMS