diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | rand.c | 46 |
2 files changed, 32 insertions, 21 deletions
@@ -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. @@ -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) |