RandMT.h

#pragma once
#ifndef MT_RAND_H
#define MT_RAND_H

// An implementation of the Mersenne Twister pseudo-random number generator proposed by
// Makoto Matsumoto and Makoto Matsumoto. The algorithm itself is currently released by the authors
// for any use, including commercial. My code was adapted by code written by the original authors,
// as a learning experience. You're free to use and edit it in any way you like.

void seedMT(unsigned long seed);
unsigned long randMT();

#endif

RandMT.cpp

#include "RandMT.h"
#include <time.h>

// Period perameters changed to const values
const int N = 624;
const int M = 397;
const unsigned long F = 1812433253;
const unsigned long A = 0x9908bd0df;
const unsigned long UPPER_MASK = 0x80000000;
const unsigned long LOWER_MASK = 0x7fffffff;

// Tempering parameters
const int u = 11;
const int s = 7;
const int t = 15;
const int l = 18;
const int d = 0xffffffff;
const unsigned long b = 0x9d2c5680;
const unsigned long c = 0xefc60000;

// State of the PRNG
unsigned long mt[N];
int mti = N + 1;

// Seed the PRNG
void seedMT(unsigned long seed) {
	mt[0] = seed & 0xffffffff;
	for (mti = 1; mti < N; mti++) {
		mt[mti] = (F * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti);
		mt[mti] &= d;
	}
}

// Return a random numbr in range [0, ULONG_MAX)
unsigned long randMT() {
	unsigned long y;
	static unsigned long mag01[2] = { 0x0UL, A };

	if (mti >= N) {

		// If the generator has not been seeded it, seed it with a default seed
		// I opt to use time instead of 5489.
		if (mti == N + 1) { seedMT((unsigned long)time(NULL)); }

		for (int kk = 0; kk < N - M; kk++) {
			y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
			mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
		}

		for (int kk = N - M; kk> 1) ^ mag01[y & 0x1UL];
		}

		y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
		mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
		mti = 0;
	}

	y = mt[mti++];

	// Tempering algorithm
	y ^= (y >> u);
	y ^= (y << s) & b;
	y ^= (y << t) & c;
	y ^= (y >> l);

	return y;
}