73 const MTRand::uint32 MTRand::state_size;
75 MTRand MTRand::instance;
77 static const MTRand::uint32 period = 397;
78 static const MTRand::uint32 MATRIX_A = 0x9908b0df;
79 static const MTRand::uint32 UPPER_MASK = 0x80000000;
80 static const MTRand::uint32 LOWER_MASK = 0x7fffffff;
83 static MTRand::uint32 hash( time_t t, clock_t c )
89 typedef MTRand::uint32 uint32;
92 static uint32 differ = 0;
95 auto *p = (
unsigned char *) &t;
96 for(
size_t i = 0; i <
sizeof(t); ++i )
102 p = (
unsigned char *) &c;
103 for(
size_t j = 0; j <
sizeof(c); ++j )
105 h2 *= UCHAR_MAX + 2U;
108 return ( h1 + differ++ ) ^ h2;
115 FILE* urandom = fopen(
"/dev/urandom",
"rb" );
118 uint32 init_vector[state_size];
119 uint32 *s = init_vector;
122 while( success && i-- )
123 success = fread( s++,
sizeof(uint32), 1, urandom );
125 if( success ) { seed( init_vector, state_size );
return; }
129 seed( hash( time(
nullptr), clock() ) );
133 void MTRand::seed(uint32 s)
136 for (index = 1; index < state_size; ++index)
138 state[index] = (1812433253UL * (state[index-1] ^ (state[index-1] >> 30u)) + index);
143 void MTRand::seed(
const uint32 init_vector[],
const uint32 init_vector_length)
148 uint32 k = (state_size > init_vector_length ? state_size : init_vector_length);
151 state[i] ^= ((state[i-1] ^ (state[i-1] >> 30u)) * 1664525UL);
152 state[i] += (init_vector[j] & 0xffffffffUL) + j;
154 if (i >= state_size) { state[0] = state[state_size-1]; i = 1; }
155 if (j >= init_vector_length) j = 0;
157 for (k = state_size - 1; k; --k)
159 state[i] ^= ((state[i-1] ^ (state[i-1] >> 30u)) * 1566083941UL);
162 if (i >= state_size) { state[0] = state[state_size-1]; i = 1; }
164 state[0] = 0x80000000UL;
168 MTRand::uint32 MTRand::randInt()
171 static unsigned long mag01[2]={0x0UL, MATRIX_A};
174 if (index >= state_size)
177 for (kk=0; kk < state_size - period; kk++)
179 y = (state[kk]&UPPER_MASK) | (state[kk+1]&LOWER_MASK);
180 state[kk] = state[kk + period] ^ (y >> 1u) ^ mag01[y & 0x01u];
182 for (; kk < state_size-1; kk++)
184 y = (state[kk]&UPPER_MASK) | (state[kk+1]&LOWER_MASK);
185 state[kk] = state[kk+(period - state_size)] ^ (y >> 1u) ^ mag01[y & 0x01u];
187 y = (state[state_size-1]&UPPER_MASK) | (state[0]&LOWER_MASK);
188 state[state_size-1] = state[period-1] ^ (y >> 1u) ^ mag01[y & 0x1UL];
197 y ^= (y << 7u) & 0x9d2c5680UL;
198 y ^= (y << 15u) & 0xefc60000UL;
205 std::ostream& MTRand::save(std::ostream& ostr)
const
211 return ostr << index;
215 std::istream& MTRand::load(std::istream& istr)
217 for (
auto & i : state)
Generic library namespace.