const N = 624 const M = 397 function twist (u, v) { return ((((u & 0x80000000) | (v & 0x7fffffff)) >>> 1) ^ ((v & 1) ? 0x9908b0df : 0)) } function nextState (state) { let p = 0 let j for (j = N - M + 1; --j; p++) { state[p] = state[p + M] ^ twist(state[p], state[p + 1]) } for (j = M; --j; p++) { state[p] = state[p + M - N] ^ twist(state[p], state[p + 1]) } state[p] = state[p + M - N] ^ twist(state[p], state[0]) } /** * This is a port of Shawn Cokus's implementation of the original Mersenne Twister algorithm (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/MTARCOK/mt19937ar-cok.c). * MT has a very high period of 2^19937. Though the authors of xorshift describe that a high period is not * very relevant (http://vigna.di.unimi.it/xorshift/). It is four times slower than xoroshiro128plus and * needs to recompute its state after generating 624 numbers. * * @example * const gen = new Mt19937(new Date().getTime()) * console.log(gen.next()) * * @public */ export default class Mt19937 { /** * @param {Number} seed The starting point for the random number generation. If you use the same seed, the generator will return the same sequence of random numbers. */ constructor (seed) { this.seed = seed const state = new Uint32Array(N) state[0] = seed for (let i = 1; i < N; i++) { state[i] = (Math.imul(1812433253, (state[i - 1] ^ (state[i - 1] >>> 30))) + i) & 0xFFFFFFFF } this._state = state this._i = 0 nextState(this._state) } /** * Generate a random signed integer. * * @return {Number} A 32 bit signed integer. */ next () { if (this._i === N) { // need to compute a new state nextState(this._state) this._i = 0 } let y = this._state[this._i++] y ^= (y >>> 11) y ^= (y << 7) & 0x9d2c5680 y ^= (y << 15) & 0xefc60000 y ^= (y >>> 18) return y } }