Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Period parameters */
- #define N 624
- #define M 397
- #define MATRIX_A 0x9908b0df /* constant vector a */
- #define UPPER_MASK 0x80000000 /* most significant w-r bits */
- #define LOWER_MASK 0x7fffffff /* least significant r bits */
- /* Tempering parameters */
- #define TEMPERING_MASK_B 0x9d2c5680
- #define TEMPERING_MASK_C 0xefc60000
- #define TEMPERING_SHIFT_U(y) (y >> 11)
- #define TEMPERING_SHIFT_S(y) (y << 7)
- #define TEMPERING_SHIFT_T(y) (y << 15)
- #define TEMPERING_SHIFT_L(y) (y >> 18)
- #define RAND_MAX 0x7fffffff
- static unsigned long mt[N]; /* the array for the state vector */
- static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
- /* initializing the array with a NONZERO seed */
- void
- sgenrand(unsigned long seed)
- {
- /* setting initial seeds to mt[N] using */
- /* the generator Line 25 of Table 1 in */
- /* [KNUTH 1981, The Art of Computer Programming */
- /* Vol. 2 (2nd Ed.), pp102] */
- mt[0]= seed & 0xffffffff;
- for (mti=1; mti<N; mti++)
- mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
- }
- long /* for integer generation */
- genrand()
- {
- unsigned long y;
- static unsigned long mag01[2]={0x0, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
- if (mti >= N) { /* generate N words at one time */
- int kk;
- if (mti == N+1) /* if sgenrand() has not been called, */
- sgenrand(4357); /* a default initial seed is used */
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
- }
- for (;kk<N-1;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
- }
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
- mti = 0;
- }
- y = mt[mti++];
- y ^= TEMPERING_SHIFT_U(y);
- y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
- y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
- y ^= TEMPERING_SHIFT_L(y);
- // Strip off uppermost bit because we want a long,
- // not an unsigned long
- return y & RAND_MAX;
- }
- // Assumes 0 <= max <= RAND_MAX
- // Returns in the half-open interval [0, max]
- long random_at_most(long max) {
- unsigned long
- // max <= RAND_MAX < ULONG_MAX, so this is okay.
- num_bins = (unsigned long) max + 1,
- num_rand = (unsigned long) RAND_MAX + 1,
- bin_size = num_rand / num_bins,
- defect = num_rand % num_bins;
- long x;
- do {
- x = genrand();
- }
- // This is carefully written not to overflow
- while (num_rand - defect <= (unsigned long)x);
- // Truncated division is intentional
- return x/bin_size;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement