/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * JavaScript version of Mersenne Twister * * @author Yasuharu Okada * */ function MersenneTwister () { // eslint-disable-line no-unused-vars const N = 624 const M = 397 const UPPER_MASK = 0x80000000 const LOWER_MASK = 0x7fffffff const MAG01 = new Int32Array([0, 0x9908b0df]) let mt = new Int32Array(N) /* the array for the state vector */ let mti = 625 this.seed = function (s) { mt[0] = s | 0 for (mti = 1; mti < N; mti++) { mt[mti] = Math.imul(1812433253, mt[mti - 1] ^ (mt[mti - 1] >>> 30)) + mti } } this.export_state = function () { return [mt, mti] } this.import_state = function (s) { mt = s[0] mti = s[1] } this.export_mta = function () { return mt } this.import_mta = function (_mta) { mt = _mta } this.export_mti = function () { return mti } this.import_mti = function (_mti) { mti = _mti } this.int32 = function () { let y, kk if (mti >= N) { /* generate N words at one time */ for (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 & 0x1]) } for (; kk < N - 1; kk++) { y = ((mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK)) mt[kk] = (mt[kk + (M - N)] ^ (y >>> 1) ^ MAG01[y & 0x1]) } y = ((mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK)) mt[N - 1] = (mt[M - 1] ^ (y >>> 1) ^ MAG01[y & 0x1]) mti = 0 } y = mt[mti++] /* Tempering */ y = y ^ (y >>> 11) y = y ^ ((y << 7) & 0x9d2c5680) y = y ^ ((y << 15) & 0xefc60000) y = y ^ (y >>> 18) return y >>> 0 } this.real2 = function () { return ((this.int32() >>> 5) * 67108864.0 + (this.int32() >>> 6)) / 9007199254740992.0 } } module.exports = { MersenneTwister }