Skip to content

Instantly share code, notes, and snippets.

@1995eaton
Created October 17, 2015 23:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1995eaton/abb9a23fd89d413f78fa to your computer and use it in GitHub Desktop.
Save 1995eaton/abb9a23fd89d413f78fa to your computer and use it in GitHub Desktop.
Mersenne Twister (32 and 64 bit) C89+ header
#ifndef MT_H
#define MT_H
#define MT_GEN(TYPE, NAME, W, N, M, A, U, D, S, B, T, C, F, L, LM, UM) \
typedef struct { \
TYPE MT[N]; \
TYPE index; \
} NAME; \
void NAME##_seed(NAME *mt, TYPE seed) { \
mt->index = (N); \
mt->MT[0] = seed; \
int i; \
for (i = 1; i < (N); i++) \
mt->MT[i] = (F) * (mt->MT[i - 1] ^ mt->MT[i - 1] >> ((W) - 2)) + i; \
} \
void NAME##_twist(NAME *mt) { \
static const TYPE a_lookup[] = {0, (A)}; \
int i; \
for (i = 0; i < (N); i++) { \
TYPE x = (mt->MT[i] & (UM)) | \
(mt->MT[(i + 1) % (N)] & (LM)); \
mt->MT[i] = mt->MT[(i + (M)) % (N)] ^ \
(x >> 1) ^ a_lookup[x & 1]; \
} \
mt->index = 0; \
} \
TYPE NAME##_rand(NAME *mt) { \
if (mt->index >= (N)) \
NAME##_twist(mt); \
TYPE y = mt->MT[mt->index++]; \
y ^= (y >> (U)) & (D); \
y ^= (y << (S)) & (B); \
y ^= (y << (T)) & (C); \
return y ^ (y >> (L)); \
}
MT_GEN(uint32_t, MT19937, 32, 624, 397, 0x9908b0df, 11, 0xffffffff, 7,
0x9d2c5680, 15, 0xefc60000, 1812433253, 18, 0x7fffffff, 0x80000000)
MT_GEN(uint64_t, MT19937_64, 64, 312, 156, 0xb5026f5aa96619e9, 29,
0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000,
6364136223846793005, 43, 0x000000007fffffff, 0xffffffff80000000)
#undef MT_GEN
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment