diff options
Diffstat (limited to 'src/lib9')
-rw-r--r-- | src/lib9/lrand.c | 77 | ||||
-rw-r--r-- | src/lib9/rand.c | 81 |
2 files changed, 76 insertions, 82 deletions
diff --git a/src/lib9/lrand.c b/src/lib9/lrand.c index 47c331d9..2ebb3962 100644 --- a/src/lib9/lrand.c +++ b/src/lib9/lrand.c @@ -1,8 +1,83 @@ #include <u.h> #include <libc.h> +/* + * algorithm by + * D. P. Mitchell & J. A. Reeds + */ + +#define LEN 607 +#define TAP 273 +#define MASK 0x7fffffffL +#define A 48271 +#define M 2147483647 +#define Q 44488 +#define R 3399 +#define NORM (1.0/(1.0+MASK)) + +static ulong rng_vec[LEN]; +static ulong* rng_tap = rng_vec; +static ulong* rng_feed = 0; +static Lock lk; + +static void +isrand(long seed) +{ + long lo, hi, x; + int i; + + rng_tap = rng_vec; + rng_feed = rng_vec+LEN-TAP; + seed = seed%M; + if(seed < 0) + seed += M; + if(seed == 0) + seed = 89482311; + x = seed; + /* + * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1) + */ + for(i = -20; i < LEN; i++) { + hi = x / Q; + lo = x % Q; + x = A*lo - R*hi; + if(x < 0) + x += M; + if(i >= 0) + rng_vec[i] = x; + } +} + +void +srand(long seed) +{ + lock(&lk); + isrand(seed); + unlock(&lk); +} + long lrand(void) { - return ((rand()<<16)^rand()) & 0x7FFFFFFF; + ulong x; + + lock(&lk); + + rng_tap--; + if(rng_tap < rng_vec) { + if(rng_feed == 0) { + isrand(1); + rng_tap--; + } + rng_tap += LEN; + } + rng_feed--; + if(rng_feed < rng_vec) + rng_feed += LEN; + x = (*rng_feed + *rng_tap) & MASK; + *rng_feed = x; + + unlock(&lk); + + return x; } diff --git a/src/lib9/rand.c b/src/lib9/rand.c index 34f77eca..ecb9eac9 100644 --- a/src/lib9/rand.c +++ b/src/lib9/rand.c @@ -1,86 +1,5 @@ #include <lib9.h> -/* - * algorithm by - * D. P. Mitchell & J. A. Reeds - */ - -#define LEN 607 -#define TAP 273 -#define MASK 0x7fffffffL -#define A 48271 -#define M 2147483647 -#define Q 44488 -#define R 3399 -#define NORM (1.0/(1.0+MASK)) - -static ulong rng_vec[LEN]; -static ulong* rng_tap = rng_vec; -static ulong* rng_feed = 0; -static Lock lk; - -static void -isrand(long seed) -{ - long lo, hi, x; - int i; - - rng_tap = rng_vec; - rng_feed = rng_vec+LEN-TAP; - seed = seed%M; - if(seed < 0) - seed += M; - if(seed == 0) - seed = 89482311; - x = seed; - /* - * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1) - */ - for(i = -20; i < LEN; i++) { - hi = x / Q; - lo = x % Q; - x = A*lo - R*hi; - if(x < 0) - x += M; - if(i >= 0) - rng_vec[i] = x; - } -} - -void -srand(long seed) -{ - lock(&lk); - isrand(seed); - unlock(&lk); -} - -long -lrand(void) -{ - ulong x; - - lock(&lk); - - rng_tap--; - if(rng_tap < rng_vec) { - if(rng_feed == 0) { - isrand(1); - rng_tap--; - } - rng_tap += LEN; - } - rng_feed--; - if(rng_feed < rng_vec) - rng_feed += LEN; - x = (*rng_feed + *rng_tap) & MASK; - *rng_feed = x; - - unlock(&lk); - - return x; -} - int rand(void) { |