1 /* r250.c the r250 uniform random number algorithm
3 Kirkpatrick, S., and E. Stoll, 1981; "A Very Fast
4 Shift-Register Sequence Random Number Generator",
5 Journal of Computational Physics, V.40
9 see W.L. Maier, DDJ May 1991
19 static unsigned int randlcg();
22 #define MSB 0x80000000L
23 #define ALL_BITS 0xffffffffL
24 #define HALF_RANGE 0x40000000L
28 static unsigned int r250_buffer
[ 250 ];
29 static int r250_index
;
31 static unsigned int randlcg(int sd
) /* returns a random unsigned integer */
33 static long quotient1
= LONG_MAX
/ 16807L;
34 static long remainder1
= LONG_MAX
% 16807L;
36 if ( sd
<= quotient1
)
37 sd
= (sd
* 16807L) % LONG_MAX
;
40 int high_part
= sd
/ quotient1
;
41 int low_part
= sd
% quotient1
;
43 int test
= 16807L * low_part
- remainder1
* high_part
;
55 void r250_init(int sd
)
58 unsigned int mask
, msb
;
61 for (j
= 0; j
< 250; j
++) /* fill r250 buffer with BITS-1 bit values */
62 sd
= r250_buffer
[j
] = randlcg(sd
);
65 for (j
= 0; j
< 250; j
++) /* set some MSBs to 1 */
66 if ( (sd
=randlcg(sd
)) > HALF_RANGE
)
67 r250_buffer
[j
] |= MSB
;
70 msb
= MSB
; /* turn on diagonal bit */
71 mask
= ALL_BITS
; /* turn off the leftmost bits */
73 for (j
= 0; j
< BITS
; j
++)
75 k
= STEP
* j
+ 3; /* select a word to operate on */
76 r250_buffer
[k
] &= mask
; /* turn off bits left of the diagonal */
77 r250_buffer
[k
] |= msb
; /* turn on the diagonal bit */
84 unsigned int r250() /* returns a random unsigned integer */
87 register unsigned int new_rand
;
89 if ( r250_index
>= 147 )
90 j
= r250_index
- 147; /* wrap pointer around */
94 new_rand
= r250_buffer
[ r250_index
] ^ r250_buffer
[ j
];
95 r250_buffer
[ r250_index
] = new_rand
;
97 if ( r250_index
>= 249 ) /* increment pointer for next time */
107 double dr250() /* returns a random double in range 0..1 */
110 register unsigned int new_rand
;
112 if ( r250_index
>= 147 )
113 j
= r250_index
- 147; /* wrap pointer around */
115 j
= r250_index
+ 103;
117 new_rand
= r250_buffer
[ r250_index
] ^ r250_buffer
[ j
];
118 r250_buffer
[ r250_index
] = new_rand
;
120 if ( r250_index
>= 249 ) /* increment pointer for next time */
125 return (double)new_rand
/ ALL_BITS
;