summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-05 07:19:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-05 07:19:34 -0700
commit33832ea317f8fc57c251e0dce04b67760a378bac (patch)
tree1b778bb2f6db29cdb81c14463e585ec7846dc8a2
parent6c2bc5ad087e74dea68585c6bf876a038d9e324f (diff)
downloadtxr-33832ea317f8fc57c251e0dce04b67760a378bac.tar.gz
txr-33832ea317f8fc57c251e0dce04b67760a378bac.tar.bz2
txr-33832ea317f8fc57c251e0dce04b67760a378bac.zip
* rand.c (make_random_state): Make the seeding behavior
portable when the seed is a fixnum or bignum. The goal is that the same values of seed should produce the same random sequences on any platform.
-rw-r--r--ChangeLog7
-rw-r--r--rand.c20
2 files changed, 20 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 42bbbaac..cd9503ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2014-08-05 Kaz Kylheku <kaz@kylheku.com>
+ * rand.c (make_random_state): Make the seeding behavior
+ portable when the seed is a fixnum or bignum. The goal is that the same
+ values of seed should produce the same random sequences on any
+ platform.
+
+2014-08-05 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (eval_init): Fix incorrect registration of
random-fixnum, which doesn't allow it to be called
with no arguments.
diff --git a/rand.c b/rand.c
index 5e583f76..3ebc6842 100644
--- a/rand.c
+++ b/rand.c
@@ -125,19 +125,25 @@ val make_random_state(val seed)
dig++, bit = 0;
}
- for (; i < 16; i++) {
- r->state[i] = 0xAAAAAAAA;
- }
+ while (i > 0 && !r->state[i - 1])
+ i--;
+
+ if (i < 16)
+ memset(r->state + i, 0xAA, sizeof r->state - i * sizeof r->state[0]);
} else if (fixnump(seed)) {
cnum s = c_num(seed) & NUM_MAX;
memset(r->state, 0xAA, sizeof r->state);
r->state[0] = s & 0xFFFFFFFFul;
#if SIZEOF_PTR >= 8
- r->state[1] = (s >> 32) & 0xFFFFFFFFul;
-#elif SIZEOF_PTR >= 16
- r->state[2] = (s >> 64) & 0xFFFFFFFFul;
- r->state[3] = (s >> 96) & 0xFFFFFFFFul;
+ s >>= 32;
+ if (s)
+ r->state[1] = s & 0xFFFFFFFFul;
+#endif
+#if SIZEOF_PTR >= 16
+ s >>= 32;
+ if (s)
+ r->state[2] = s & 0xFFFFFFFFul;
#endif
} else if (nilp(seed)) {
val time = time_sec_usec();