pcg-random
Version:
Implementation of the PCG random number generator for JavaScript
54 lines (51 loc) • 2.12 kB
JavaScript
var stepBigint = NO_BIGINTS ? noBigInts : (function() {
var BI_U32_MAX = BigInt(0xffffffff);
var BI_27 = BigInt(27);
var BI_18 = BigInt(18);
var BI_59 = BigInt(59);
var BI_31 = BigInt(31);
var BI_32 = BigInt(32);
var BI_U64_MAX = ((BI_U32_MAX << BI_32) | BI_U32_MAX);
var BI_MUL = (BigInt(MUL_HI) << BI_32) | BigInt(MUL_LO);
function mix(oldState) {
var xorshifted = (((oldState >> BI_18) ^ oldState) >> BI_27) & BI_U32_MAX;
var rot = (oldState >> BI_59);
var nrot = (-rot) & BI_31;
var result = ((xorshifted >> rot) | (xorshifted << nrot)) & BI_U32_MAX;
return result;
}
function finish(stateArr, newState, result) {
stateArr[0] = Number(newState & BI_U32_MAX);
stateArr[1] = Number((newState >> BI_32) & BI_U32_MAX);
return Number(result) >>> 0;
}
function stepBigint(stateArr) {
var oldState = (BigInt(stateArr[1]) << BI_32) | BigInt(stateArr[0]);
var inc = (BigInt(stateArr[3]) << BI_32) | BigInt(stateArr[2]);
var newState = ((oldState * BI_MUL) + inc) & BI_U64_MAX;
var result = mix(oldState, inc);
return finish(stateArr, newState, result);
}
return stepBigint;
}());
/**
* By default, if `BigInt` support is detected, we'll use them for certain
* operations in the internals.
*
* This is intended to be more efficient, but it may turn out that this
* causes performance problems for certain JavaScript implementations.
*
* If this is the case, you can set `PcgRandom.NO_BIGINTS = false`, and
* we'll never use them, even if they are available. I'd be interested to
* hear if you have this issue (I expect it might be possible though,
* because bigints generate garbage...).
*
* (Note that this only impacts whether we use bigints internally, and
* nothing about the API. The `setSeed` "overload" that accepts bigints will
* still work if you disable this).
*
* Note that while this defaults to `true` when bigints are supported, it is
* safe to set this to `true` even if they are not. We will only use bigints
* `if (PcgRandom.USE_BIGINTS && !NO_BIGINTS)`.
*/
PcgRandom.USE_BIGINTS = !NO_BIGINTS;