Blob
1 #include <u.h>2 #include <libc.h>4 /*5 * algorithm by6 * D. P. Mitchell & J. A. Reeds7 */9 #define LEN 60710 #define TAP 27311 #define MASK 0x7fffffffL12 #define A 4827113 #define M 214748364714 #define Q 4448815 #define R 339916 #define NORM (1.0/(1.0+MASK))18 static ulong rng_vec[LEN];19 static ulong* rng_tap = rng_vec;20 static ulong* rng_feed = 0;21 static Lock lk;23 static void24 isrand(long seed)25 {26 long lo, hi, x;27 int i;29 rng_tap = rng_vec;30 rng_feed = rng_vec+LEN-TAP;31 seed = seed%M;32 if(seed < 0)33 seed += M;34 if(seed == 0)35 seed = 89482311;36 x = seed;37 /*38 * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1)39 */40 for(i = -20; i < LEN; i++) {41 hi = x / Q;42 lo = x % Q;43 x = A*lo - R*hi;44 if(x < 0)45 x += M;46 if(i >= 0)47 rng_vec[i] = x;48 }49 }51 void52 p9srand(long seed)53 {54 lock(&lk);55 isrand(seed);56 unlock(&lk);57 }59 long60 p9lrand(void)61 {62 ulong x;64 lock(&lk);66 rng_tap--;67 if(rng_tap < rng_vec) {68 if(rng_feed == 0) {69 isrand(1);70 rng_tap--;71 }72 rng_tap += LEN;73 }74 rng_feed--;75 if(rng_feed < rng_vec)76 rng_feed += LEN;77 x = (*rng_feed + *rng_tap) & MASK;78 *rng_feed = x;80 unlock(&lk);82 return x;83 }