// Mersenne twister pseudorandom number generator // According to Wikipedia // provides: // struct rand; // rand_t init_rand(int seed); // int rand(rand_t gen); #include "rand.h0" struct rand { int[] MT; int index; }; // Right shift in C0 is arithmetic; need // to implement a zero-fill right shift // as y>>>k = (y>>k)&~(-1<<(32-k)) (1 <= k <= 31) void generateNumbers(rand_t gen) { int[] MT = gen->MT; int i; for (i = 0; i < 624; i++) { int y = (MT[i] & 0x80000000) + (MT[(i+1)%624] & 0x7fffffff); MT[i] = MT[(i+397)%624] ^ ((y>>1) & ~(-1<<31)); if ((y & 1) == 1) MT[i] ^= 0x9908b0df; } } rand_t init_rand(int seed) { rand_t gen = alloc(struct rand); int[] MT = alloc_array(int, 624); int i; gen->MT = MT; gen->index = 0; MT[0] = seed; for (i = 1; i < 624; i++) MT[i] = 0x6c078965 * (MT[i-1] ^ ((MT[i-1]>>30) & ~(-1<<2))) + i; return gen; } int rand(rand_t gen) { if (gen->index == 0) generateNumbers(gen); { int[] MT = gen->MT; int y = MT[gen->index]; y ^= (y >> 11) & ~(-1<<21); y ^= (y << 7) & 0x9d2c5680; y ^= (y << 15) & 0xefc60000; y ^= (y >> 18) & ~(-1<<14); gen->index = (gen->index + 1) % 624; return y; } }