Last active
July 13, 2018 13:53
-
-
Save Pepijn98/e5951709437f2463728eb657a2f5a394 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author KurozeroPB | |
*/ | |
class Numbers { | |
/** | |
* Create a new instance | |
* @param {Number|Number[]} seed | |
*/ | |
constructor(seed) { | |
if (seed == undefined) { | |
seed = new Date().getTime(); | |
} | |
this.N = 624; | |
this.M = 397; | |
this.MATRIX_A = 0x9908b0df; | |
this.UPPER_MASK = 0x80000000; | |
this.LOWER_MASK = 0x7fffffff; | |
this.mt = new Array(this.N); | |
this.mti = this.N + 1; | |
if (seed instanceof Array) { | |
this.init_by_array(seed, seed.length); | |
} else { | |
this.init_seed(seed); | |
} | |
} | |
/** | |
* Initialize with number | |
* @param {Number} sd | |
*/ | |
init_seed(sd) { | |
this.mt[0] = sd >>> 0; | |
for (this.mti = 1; this.mti < this.N; this.mti++) { | |
var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30); | |
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + this.mti; | |
this.mt[this.mti] >>>= 0; | |
} | |
} | |
/** | |
* Initialize with number array | |
* @param {Number[]} init_key | |
* @param {Number} key_length | |
*/ | |
init_by_array(init_key, key_length) { | |
var i, j, k; | |
this.init_seed(19650218); | |
i = 1; | |
j = 0; | |
k = (this.N > key_length ? this.N : key_length); | |
for (; k; k--) { | |
var s1 = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); | |
this.mt[i] = (this.mt[i] ^ (((((s1 & 0xffff0000) >>> 16) * 1664525) << 16) + ((s1 & 0x0000ffff) * 1664525))) + init_key[j] + j; | |
this.mt[i] >>>= 0; | |
i++; | |
j++; | |
if (i >= this.N) { | |
this.mt[0] = this.mt[this.N - 1]; | |
i = 1; | |
} | |
if (j >= key_length) j = 0; | |
} | |
for (k = this.N - 1; k; k--) { | |
var s2 = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); | |
this.mt[i] = (this.mt[i] ^ (((((s2 & 0xffff0000) >>> 16) * 1566083941) << 16) + (s2 & 0x0000ffff) * 1566083941)) - i; | |
this.mt[i] >>>= 0; | |
i++; | |
if (i >= this.N) { | |
this.mt[0] = this.mt[this.N - 1]; | |
i = 1; | |
} | |
} | |
this.mt[0] = 0x80000000; | |
} | |
/** | |
* Generates a random number on [0,0xffffffff] interval | |
* @returns {Number} | |
*/ | |
random_int() { | |
var y; | |
var mag01 = [0x0, this.MATRIX_A]; | |
if (this.mti >= this.N) { | |
var kk; | |
if (this.mti == this.N + 1) this.init_seed(5489); | |
for (kk = 0; kk < this.N - this.M; kk++) { | |
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); | |
this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
} | |
for (; kk < this.N - 1; kk++) { | |
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); | |
this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
} | |
y = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK); | |
this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
this.mti = 0; | |
} | |
y = this.mt[this.mti++]; | |
y ^= (y >>> 11); | |
y ^= (y << 7) & 0x9d2c5680; | |
y ^= (y << 15) & 0xefc60000; | |
y ^= (y >>> 18); | |
return y >>> 0; | |
} | |
/** | |
* Generates a random number on [0,0x7fffffff] interval | |
* @returns {Number} | |
*/ | |
random_int31() { | |
return (this.random_int() >>> 1); | |
} | |
/** | |
* Generates a random number on [0,1] real-interval | |
* @returns {Number} | |
*/ | |
random_incl() { | |
return this.random_int() * (1.0 / 4294967295.0); | |
} | |
/** | |
* Generates a random number on [0,1] real-interval | |
* @returns {Number} | |
*/ | |
random() { | |
return this.random_int() * (1.0 / 4294967296.0); | |
} | |
/** | |
* Generates a random number on [0,1] real-interval | |
* @returns {Number} | |
*/ | |
random_excl() { | |
return (this.random_int() + 0.5) * (1.0 / 4294967296.0); | |
} | |
/** | |
* Generates a random number on [0,1] with 53-bit resolution | |
* @returns {Number} | |
*/ | |
random_long() { | |
var a = this.random_int() >>> 5, b = this.random_int() >>> 6; | |
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment