1 #include "misc/auxiliary.h"
2 #include "sirandom.h"
3
4 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
5 /*
6 *
7 * A prime modulus multiplicative linear congruential
8 * generator (PMMLCG), or "Lehmer generator".
9 * Implementation directly derived from the article:
10 *
11 * S. K. Park and K. W. Miller
12 * Random Number Generators: Good Ones are Hard to Find
13 * CACM vol 31, #10. Oct. 1988. pp 1192-1201.
14 *
15 * Using the following multiplier and modulus, we obtain a
16 * generator which:
17 *
18 * 1) Has a full period: 1 to 2^31 - 2.
19 * 2) Is testably "random" (see the article).
20 * 3) Has a known implementation by E. L. Schrage.
21 */
22
23
24 #define A 16807 /* A "good" multiplier */
25 #define M 2147483647 /* Modulus: 2^31 - 1 */
26 #define Q 127773 /* M / A */
27 #define R 2836 /* M % A */
28
29
30 VAR int siSeed = 1;
31
siRandNext(int r)32 int siRandNext(int r)
33 {
34 r = A * (r % Q) - R * (r / Q);
35
36 if ( r < 0 )
37 r += M;
38
39 return( r );
40 }
41
siRand()42 int siRand()
43 {
44 siSeed=siRandNext(siSeed);
45 return siSeed;
46 }
siRandPlus1(int r)47 int siRandPlus1(int r)
48 {
49 return r+1;
50 }
51