summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--rand.c46
2 files changed, 32 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 3d5d6aaf..996a7e28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2011-12-23 Kaz Kylheku <kaz@kylheku.com>
+ * rand.c (rand32): Moved.
+ (make_random_state): After initializing, retrieve eight
+ random numbers to clear pathological initial behavior
+ leading to duplicate values.
+
+2011-12-23 Kaz Kylheku <kaz@kylheku.com>
+
* arith.c (highest_bit): Changing to external linkage.
* arith.h (highest_bit): Declared.
diff --git a/rand.c b/rand.c
index 073aa62e..9a48e7e1 100644
--- a/rand.c
+++ b/rand.c
@@ -80,9 +80,31 @@ val random_state_p(val obj)
return typeof(obj) == random_state_s ? t : nil;
}
+static rand32_t rand32(struct random_state *r)
+{
+ #define RSTATE(r,i) ((r)->state[((r)->cur + i) % 16])
+ rand32_t s0 = RSTATE(r, 0);
+ rand32_t s9 = RSTATE(r, 9);
+ rand32_t s13 = RSTATE(r, 13);
+ rand32_t s15 = RSTATE(r, 15);
+
+ rand32_t r1 = s0 ^ (s0 << 16) ^ s13 ^ (s13 << 15);
+ rand32_t r2 = s9 ^ (s9 >> 11);
+
+ rand32_t ns0 = RSTATE(r, 0) = r1 ^ r2;
+ rand32_t ns15 = s15 ^ (s15 << 2) ^ r1 ^ (r1 << 18) ^ r2 ^ (r2 << 28) ^
+ ((ns0 ^ (ns0 << 5)) & 0xda442d24ul);
+
+ RSTATE(r, 15) = ns15;
+ r->cur = (r->cur + 15) % 16;
+ return ns15;
+ #undef RSTATE
+}
+
val make_random_state(val seed)
{
val rs = make_state();
+ int i;
struct random_state *r = (struct random_state *)
cobj_handle(rs, random_state_s);
@@ -126,28 +148,10 @@ val make_random_state(val seed)
seed, nao);
}
- return rs;
-}
+ for (i = 0; i < 8; i++)
+ (void) rand32(r);
-static rand32_t rand32(struct random_state *r)
-{
- #define RSTATE(r,i) ((r)->state[((r)->cur + i) % 16])
- rand32_t s0 = RSTATE(r, 0);
- rand32_t s9 = RSTATE(r, 9);
- rand32_t s13 = RSTATE(r, 13);
- rand32_t s15 = RSTATE(r, 15);
-
- rand32_t r1 = s0 ^ (s0 << 16) ^ s13 ^ (s13 << 15);
- rand32_t r2 = s9 ^ (s9 >> 11);
-
- rand32_t ns0 = RSTATE(r, 0) = r1 ^ r2;
- rand32_t ns15 = s15 ^ (s15 << 2) ^ r1 ^ (r1 << 18) ^ r2 ^ (r2 << 28) ^
- ((ns0 ^ (ns0 << 5)) & 0xda442d24ul);
-
- RSTATE(r, 15) = ns15;
- r->cur = (r->cur + 15) % 16;
- return ns15;
- #undef RSTATE
+ return rs;
}
val random_fixnum(val state)