An actual explanation would require first taking a few years to get a math degree, but I can give you my version of the main state advance code from ojrandlib, which is simpler than most of what you'll find on the net. My structure g
holds the generator state: g->state
is the MT state vector itself, g->buf
is an output buffer of the returned random bits:
int i, j, k, n = g->statesize;
uint32_t y, m, *s = g->state, *bp = g->buf + g->bufsize;
for (i = 0; i < n; ++i) {
j = i + 1; if (j >= n) j -= n;
k = i + 397; if (k >= n) k -= n;
m = (s[j] & 1) ? 0x9908b0df : 0;
s[i] = m ^ s[k] ^ (((s[i] & 0x80000000) | (s[j] & 0x7FFFFFFF)) >> 1);
}
for (i = 0; i < n; ++i) {
y = s[i] ^ (s[i] >> 11);
y ^= (y << 7) & 0x9d2c5680U;
y ^= (y << 15) & 0xefc60000U;
*--bp = y ^ (y >> 18);
}