/* * A simple Mersenne Twister implementation in C * Author: Nicholas Kamper (kampernj@rose-hulman.edu) * * Based on http://en.wikipedia.org/wiki/Mersenne_twister#Pseudocode */ #include #include #include #include #include "mt.h" int mt_currentIndex = 0; uint32_t mt_state[MT_SIZE]; void mt_seed(uint32_t seed) { if (seed == 0) { seed = time(NULL); } mt_state[0] = seed; int index; for (index = 1; index < MT_SIZE; index++) { mt_state[index] = (MT_INIT_COEF * (mt_state[index - 1] ^ (mt_state[index - 1] >> 30)) + index) & MT_32B_MASK; } mt_currentIndex = 0; } void mt_generateNumbers() { int index; for (index = 0; index < MT_SIZE; index++) { uint32_t y = (mt_state[index] & 0x80000000)|(mt_state[(index + 1) % 624] & 0x7FFFFFFF); mt_state[index] = mt_state[(index + 397) % 624] ^ (y >> 1); if ((y % 2) != 0) { mt_state[index] = mt_state[index] ^ 0x9908B0DF; } } } uint32_t mt_rand(uint32_t max) { if (mt_state[0] == 0) { mt_seed(0); } if (mt_currentIndex == 0) { mt_generateNumbers(); } uint32_t y = mt_state[mt_currentIndex]; y = y ^ (y >> 11); y = y ^ ((y << 7) & MT_SB_COEF); y = y ^ ((y << 15) & MT_TC_COEF); y = y ^ (y >> 18); mt_currentIndex = (mt_currentIndex + 1) % 624; return y % max; }