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