summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-22 17:27:54 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-22 17:27:54 -0800
commitba37a43bf36c5f4e787fceb18cb0f4223e98f261 (patch)
tree8a3941a6809f62641cc82c29af22f0799bcea68d
parent5a00d4815ac646ac275c93203a423b3c7aa1c2a0 (diff)
downloadtxr-ba37a43bf36c5f4e787fceb18cb0f4223e98f261.tar.gz
txr-ba37a43bf36c5f4e787fceb18cb0f4223e98f261.tar.bz2
txr-ba37a43bf36c5f4e787fceb18cb0f4223e98f261.zip
* rand.c (random): Fix for 64 bit fixnums: stick two random numbers
together. Otherwise for fixnum moduli, we get only a 32 bit number no matter what the modulus is.
-rw-r--r--ChangeLog6
-rw-r--r--rand.c4
2 files changed, 10 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ce4fd22..8eb46034 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2011-12-22 Kaz Kylheku <kaz@kylheku.com>
+ * rand.c (random): Fix for 64 bit fixnums: stick two random numbers
+ together. Otherwise for fixnum moduli, we get only a 32 bit number no
+ matter what the modulus is.
+
+2011-12-22 Kaz Kylheku <kaz@kylheku.com>
+
* stream.c (vformat): Combine ~a and ~s cases, so numbers and
strings are printed the same way under ~s and ~a. The only difference
is printing other kinds of objects.
diff --git a/rand.c b/rand.c
index 2e504514..c48ff191 100644
--- a/rand.c
+++ b/rand.c
@@ -197,7 +197,11 @@ val random(val state, val modulus)
cnum m = c_num(modulus);
if (m <= 0)
goto invalid;
+#if SIZEOF_PTR >= 8
+ return num(((((cnum) rand32(r) & 0x7FFFFFFF) << 32) | rand32(r)) % m);
+#else
return num(rand32(r) % m);
+#endif
}
invalid:
uw_throwf(numeric_error_s, lit("random: invalid modulus ~s"),