diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-08-26 23:00:31 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 18:20:04 +0900 |
| commit | 3e71359d7ac58d4bf9cc0b205f246324916d4f40 (patch) | |
| tree | cd28c00e2bf1947690eca5586983aa9abed0c328 /mrbgems/mruby-random | |
| parent | 2b188ed8a191257f23ddf6f8a27bf1d3964587ed (diff) | |
| download | mruby-3e71359d7ac58d4bf9cc0b205f246324916d4f40.tar.gz mruby-3e71359d7ac58d4bf9cc0b205f246324916d4f40.zip | |
Update `mruby-random` gem to support 32 bit platforms.
`sizeof(rand_state)` had been bigger than `sizeof(void*)*3`. Changed
random number generator to `Xorshift96` on 32 bit platforms.
Diffstat (limited to 'mrbgems/mruby-random')
| -rw-r--r-- | mrbgems/mruby-random/src/random.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index 5fa15c508..37b100084 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -34,13 +34,18 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */ The state must be seeded so that it is not everywhere zero. */ -static inline uint32_t -rotl(const uint32_t x, int k) { - return (x << k) | (x >> (32 - k)); -} +#ifdef MRB_32BIT +# define XORSHIFT96 +# define NSEEDS 3 +# define SEEDPOS 2 +#else +# define NSEEDS 4 +# define SEEDPOS 0 +#endif +#define LASTSEED (NSEEDS-1) typedef struct rand_state { - uint32_t seed[4]; + uint32_t seed[NSEEDS]; } rand_state; static void @@ -49,21 +54,45 @@ rand_init(rand_state *t) t->seed[0] = 123456789; t->seed[1] = 362436069; t->seed[2] = 521288629; +#ifndef XORSHIFT96 t->seed[3] = 88675123; +#endif } static uint32_t rand_seed(rand_state *t, uint32_t seed) { - uint32_t old_seed = t->seed[0]; + uint32_t old_seed = t->seed[SEEDPOS]; rand_init(t); - t->seed[0] = seed; + t->seed[SEEDPOS] = seed; return old_seed; } +#ifndef XORSHIFT96 +static inline uint32_t +rotl(const uint32_t x, int k) { + return (x << k) | (x >> (32 - k)); +} +#endif + static uint32_t rand_uint32(rand_state *state) { +#ifdef XORSHIFT96 + uint32_t *seed = state->seed; + uint32_t x = seed[0]; + uint32_t y = seed[1]; + uint32_t z = seed[2]; + uint32_t t; + + t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6)); + x = y; y = z; z = t; + seed[0] = x; + seed[1] = y; + seed[2] = z; + + return z; +#else uint32_t *s = state->seed; const uint32_t result = rotl(s[0] + s[3], 7) + s[0]; const uint32_t t = s[1] << 9; @@ -77,7 +106,8 @@ rand_uint32(rand_state *state) s[3] = rotl(s[3], 11); return result; -} +#endif /* XORSHIFT96 */ + } #ifndef MRB_NO_FLOAT static double |
