3 L'Ecuyer's two-sequence generator with a Bays-Durham shuffle
4 on the back-end. Schrage's algorithm is used to perform
5 64-bit modular arithmetic within the 32-bit constraints of
8 Bays, C. and S. D. Durham. ACM Trans. Math. Software: 2 (1976)
11 L'Ecuyer, P. Communications of the ACM: 31 (1968) 742-774.
13 Schrage, L. ACM Trans. Math. Software: 5 (1979) 132-138.
17 function uGen(old, a, q, r, m) { // Schrage's modular multiplication algorithm
20 t = Math.floor(old / q);
21 t = a * (old - (t * q)) - (t * r);
22 return Math.round((t < 0) ? (t + m) : t);
25 function LEnext() { // Return next raw value
28 this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
29 this.gen2 = uGen(this.gen2, 40692, 52774, 3791, 2147483399);
31 /* Extract shuffle table index from most significant part
32 of the previous result. */
34 i = Math.floor(this.state / 67108862);
36 // New state is sum of generators modulo one of their moduli
38 this.state = Math.round((this.shuffle[i] + this.gen2) % 2147483563);
40 // Replace value in shuffle table with generator 1 result
42 this.shuffle[i] = this.gen1;
47 // Return next random integer between 0 and n inclusive
52 // Determine smallest p, 2^p > n
59 /* Generate values from 0 through n by first masking
60 values v from 0 to (2^p)-1, then discarding any results v > n.
61 For the rationale behind this (and why taking
62 values mod (n + 1) is biased toward smaller values, see
63 Ferguson and Schneier, "Practical Cryptography",
64 ISBN 0-471-22357-3, section 10.8). */
67 var v = this.next() & p;
75 // Constructor. Called with seed value
80 this.shuffle = new Array(32);
81 this.gen1 = this.gen2 = (s & 0x7FFFFFFF);
82 for (i = 0; i < 19; i++) {
83 this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
86 // Fill the shuffle table with values
88 for (i = 0; i < 32; i++) {
89 this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
90 this.shuffle[31 - i] = this.gen1;
92 this.state = this.shuffle[0];
94 this.nextInt = LEnint;