src/math/core/tools/random/Xorshift.js
/**
* The script is part of konpeito.
*
* AUTHOR:
* natade (http://twitter.com/natadea)
*
* LICENSE:
* The MIT license https://opensource.org/licenses/MIT
*/
import Polyfill from "../../../tools/Polyfill.js";
import RandomBase from "./RandomBase.js";
/**
* Random number class.
* @private
* @ignore
*/
export default class Xorshift extends RandomBase {
/**
* Create Random.
* @param {number} [seed] - Seed number for random number generation. If not specified, create from time.
*/
constructor(seed) {
super();
/**
* @type {number}
* @private
* @ignore
*/
this.x = 123456789;
/**
* @type {number}
* @private
* @ignore
*/
this.y = 362436069;
/**
* @type {number}
* @private
* @ignore
*/
this.z = 521288629;
/**
* @type {number}
* @private
* @ignore
*/
this.w = 88675123;
if(seed !== undefined) {
this.setSeed(seed);
}
else {
// 線形合同法で適当に乱数を作成する
const new_seed = ((new Date()).getTime() + Xorshift.seedUniquifier) & 0xFFFFFFFF;
Xorshift.seedUniquifier = (Xorshift.seedUniquifier + 1) & 0xFFFFFFFF;
this.setSeed(new_seed);
}
}
/**
* シード値の初期化
* @param {number} seed
*/
setSeed(seed) {
// seedを使用して線形合同法で初期値を設定
let random_seed = seed;
random_seed = (Math.imul(random_seed, 214013) + 2531011) >>> 0;
this.z = random_seed;
random_seed = (Math.imul(random_seed, 214013) + 2531011) >>> 0;
this.w = random_seed;
/**
* Is keep random numbers based on Gaussian distribution.
* @private
* @type {boolean}
*/
this.haveNextNextGaussian = false;
/**
* Next random number based on Gaussian distribution.
* @private
* @type {number}
*/
this.nextNextGaussian = 0;
}
/**
* 32-bit random number.
* @returns {number} - 32-bit random number
* @ignore
*/
genrand_int32() {
const t = this.x ^ (this.x << 11);
this.x = this.y;
this.y = this.z;
this.z = this.w;
this.w = (this.w ^ (this.w >>> 19)) ^ (t ^ (t >>> 8));
return this.w;
}
}
/**
* Random number creation integer when no seed is set.
* @type {number}
* @ignore
*/
Xorshift.seedUniquifier = 0x87654321;