summaryrefslogtreecommitdiffstats
path: root/rand.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-23 22:23:38 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-23 22:23:38 -0800
commit1c8251aae0294881d0dc9fcdffeb2f86040ee24e (patch)
treefba4eaa5010051e4f4b63a70b09a0ec4594cfb8b /rand.c
parentfb2f85cff8dab72c101c48f48c69ffc6ef35204d (diff)
downloadtxr-1c8251aae0294881d0dc9fcdffeb2f86040ee24e.tar.gz
txr-1c8251aae0294881d0dc9fcdffeb2f86040ee24e.tar.bz2
txr-1c8251aae0294881d0dc9fcdffeb2f86040ee24e.zip
* rand.c (rand32): Moved.
(make_random_state): After initializing, retrieve eight random numbers to clear pathological initial behavior leading to duplicate values.
Diffstat (limited to 'rand.c')
-rw-r--r--rand.c46
1 files changed, 25 insertions, 21 deletions
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)