6cd402521cf2a7d2484a937857426ad64202047f
2 // Initial code by Bob Jenkins, March 1996 - modified in 2008
3 // Reference: http://burtleburtle.net/bob/rand/isaacafa.html
4 // Further slightly modified by Benjamin Auder, 2013
11 static uint32_t mm
[256];
12 static uint32_t aa
, bb
, cc
;
14 // initialize the (pseudo-)random generator
15 void init_rng(int flag
)
17 // 'bootstrap' isaac with basic bad PRNG
20 aa
= rand() & 0xffffffff;
21 bb
= rand() & 0xffffffff;
22 cc
= rand() & 0xffffffff;
24 uint32_t a
, b
, c
, d
, e
, f
, g
, h
, i
;
26 a
= b
= c
= d
= e
= f
= g
= h
= 0x9e3779b9;
28 for (i
= 0; i
< 4; ++i
)
29 mix(a
, b
, c
, d
, e
, f
, g
, h
);
31 // Fill in mm[] with messy stuff (the seed)
32 uint32_t seedArray
[256];
33 for (i
= 0; i
< 256; ++i
) mm
[i
] = seedArray
[i
] = rand() & 0xffffffff;
34 for (i
= 0; i
< 256; i
+= 8)
38 // Use all the information in the seed
40 b
+= seedArray
[i
+ 1];
41 c
+= seedArray
[i
+ 2];
42 d
+= seedArray
[i
+ 3];
43 e
+= seedArray
[i
+ 4];
44 f
+= seedArray
[i
+ 5];
45 g
+= seedArray
[i
+ 6];
46 h
+= seedArray
[i
+ 7];
48 mix(a
, b
, c
, d
, e
, f
, g
, h
);
61 // Do a second pass to make all of the seed affect all of mm
62 for (i
= 0; i
< 256; i
+= 8)
72 mix(a
, b
, c
, d
, e
, f
, g
, h
);
85 // return a (pseudo-)random integer
86 uint32_t get_rand_int()
88 // TODO: register variables ? (x,y,i)
90 static uint32_t i
= 0;
94 cc
= cc
+ 1; // cc just gets incremented once per 256 results
95 bb
= bb
+ cc
; // then combined with bb
115 // NOTE: bits 2..9 are chosen from x but 10..17 are chosen
116 // from y. The only important thing here is that 2..9 and 10..17
117 // don't overlap. 2..9 and 10..17 were then chosen for speed in
118 // the optimized version (rand.c) */
119 // See http://burtleburtle.net/bob/rand/isaac.html
120 // for further explanations and analysis.
122 aa
= mm
[(i
+ 128) % 256] + aa
;
123 mm
[i
] = y
= mm
[(x
>> 2) % 256] + aa
+ bb
;
124 bb
= mm
[(y
>> 10) % 256] + x
;
131 // return a (pseudo-)random real number in [0,1]
134 return (Real
) (INV_RANDMAX
* (double) get_rand_int());