Blame


1 498bb221 2004-03-21 devnull #include <u.h>
2 498bb221 2004-03-21 devnull #include <libc.h>
3 498bb221 2004-03-21 devnull
4 b37396bd 2004-12-28 devnull /*
5 b37396bd 2004-12-28 devnull * algorithm by
6 b37396bd 2004-12-28 devnull * D. P. Mitchell & J. A. Reeds
7 b37396bd 2004-12-28 devnull */
8 b37396bd 2004-12-28 devnull
9 b37396bd 2004-12-28 devnull #define LEN 607
10 b37396bd 2004-12-28 devnull #define TAP 273
11 b37396bd 2004-12-28 devnull #define MASK 0x7fffffffL
12 b37396bd 2004-12-28 devnull #define A 48271
13 b37396bd 2004-12-28 devnull #define M 2147483647
14 b37396bd 2004-12-28 devnull #define Q 44488
15 b37396bd 2004-12-28 devnull #define R 3399
16 b37396bd 2004-12-28 devnull #define NORM (1.0/(1.0+MASK))
17 b37396bd 2004-12-28 devnull
18 b37396bd 2004-12-28 devnull static ulong rng_vec[LEN];
19 b37396bd 2004-12-28 devnull static ulong* rng_tap = rng_vec;
20 b37396bd 2004-12-28 devnull static ulong* rng_feed = 0;
21 b37396bd 2004-12-28 devnull static Lock lk;
22 b37396bd 2004-12-28 devnull
23 b37396bd 2004-12-28 devnull static void
24 b37396bd 2004-12-28 devnull isrand(long seed)
25 b37396bd 2004-12-28 devnull {
26 b37396bd 2004-12-28 devnull long lo, hi, x;
27 b37396bd 2004-12-28 devnull int i;
28 b37396bd 2004-12-28 devnull
29 b37396bd 2004-12-28 devnull rng_tap = rng_vec;
30 b37396bd 2004-12-28 devnull rng_feed = rng_vec+LEN-TAP;
31 b37396bd 2004-12-28 devnull seed = seed%M;
32 b37396bd 2004-12-28 devnull if(seed < 0)
33 b37396bd 2004-12-28 devnull seed += M;
34 b37396bd 2004-12-28 devnull if(seed == 0)
35 b37396bd 2004-12-28 devnull seed = 89482311;
36 b37396bd 2004-12-28 devnull x = seed;
37 b37396bd 2004-12-28 devnull /*
38 b37396bd 2004-12-28 devnull * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1)
39 b37396bd 2004-12-28 devnull */
40 b37396bd 2004-12-28 devnull for(i = -20; i < LEN; i++) {
41 b37396bd 2004-12-28 devnull hi = x / Q;
42 b37396bd 2004-12-28 devnull lo = x % Q;
43 b37396bd 2004-12-28 devnull x = A*lo - R*hi;
44 b37396bd 2004-12-28 devnull if(x < 0)
45 b37396bd 2004-12-28 devnull x += M;
46 b37396bd 2004-12-28 devnull if(i >= 0)
47 b37396bd 2004-12-28 devnull rng_vec[i] = x;
48 b37396bd 2004-12-28 devnull }
49 b37396bd 2004-12-28 devnull }
50 b37396bd 2004-12-28 devnull
51 b37396bd 2004-12-28 devnull void
52 e25d5b71 2004-12-29 devnull p9srand(long seed)
53 b37396bd 2004-12-28 devnull {
54 b37396bd 2004-12-28 devnull lock(&lk);
55 b37396bd 2004-12-28 devnull isrand(seed);
56 b37396bd 2004-12-28 devnull unlock(&lk);
57 b37396bd 2004-12-28 devnull }
58 b37396bd 2004-12-28 devnull
59 498bb221 2004-03-21 devnull long
60 8d8865f3 2004-12-29 devnull p9lrand(void)
61 498bb221 2004-03-21 devnull {
62 b37396bd 2004-12-28 devnull ulong x;
63 b37396bd 2004-12-28 devnull
64 b37396bd 2004-12-28 devnull lock(&lk);
65 b37396bd 2004-12-28 devnull
66 fafa622a 2020-01-12 rsc if(rng_tap <= rng_vec) {
67 fafa622a 2020-01-12 rsc if(rng_feed == 0)
68 b37396bd 2004-12-28 devnull isrand(1);
69 b37396bd 2004-12-28 devnull rng_tap += LEN;
70 b37396bd 2004-12-28 devnull }
71 fafa622a 2020-01-12 rsc rng_tap--;
72 fafa622a 2020-01-12 rsc if(rng_feed <= rng_vec)
73 b37396bd 2004-12-28 devnull rng_feed += LEN;
74 fafa622a 2020-01-12 rsc rng_feed--;
75 b37396bd 2004-12-28 devnull x = (*rng_feed + *rng_tap) & MASK;
76 b37396bd 2004-12-28 devnull *rng_feed = x;
77 b37396bd 2004-12-28 devnull
78 b37396bd 2004-12-28 devnull unlock(&lk);
79 b37396bd 2004-12-28 devnull
80 b37396bd 2004-12-28 devnull return x;
81 498bb221 2004-03-21 devnull }