area51
Version:
Experimental prototypes of alien things built in JavaScript. The bits may end up living in a different package.
134 lines (108 loc) • 3.13 kB
JavaScript
/**
* Based upon the code found in https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Random.cs
* which is under the MIT License.
*/
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = Random;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var _es6SymbolJs = require("../es6/symbol.js");
var _es6SymbolJs2 = _interopRequireDefault(_es6SymbolJs);
var MBIG = 2147483647;
var MSEED = 161803398;
var MZ = 0;
var seedArray = new Array(56);
var internalSample = (0, _es6SymbolJs2["default"])();
var getSampleForLargeRange = (0, _es6SymbolJs2["default"])();
function Random(seed) {
if (!seed) {
// closest equivelant to Environment.TickCount
seed = new Date().getTime();
}
this.seedArray = new Array(56);
seed = seed || new Date().getUTCMilliseconds();
var seedArray = MSEED - (seed == -2147483648 ? MBIG : Math.abs(seed));
var num = 1;
for (var i = 1; i < 55; i++) {
var num1 = 21 * i % 55;
this.seedArray[num1] = num;
num = seedArray - num;
if (num < 0) num = num + MBIG;
seedArray = this.seedArray[num1];
}
for (var j = 1; j < 5; j++) {
for (var k = 1; k < 56; k++) {
this.seedArray[k] = this.seedArray[k] - this.seedArray[1 + (k + 30) % 55];
if (this.seedArray[k] < 0) this.seedArray[k] = this.seedArray[k] + MBIG;
}
}
this.inext = 0;
this.inextp = 21;
seed = 1;
}
;
Random.prototype = {
next: function next(minValue, maxValue) {
if (arguments.length === 0) return this[internalSample]();
if (arguments.length === 1) {
maxValue = minValue;
return Math.floor(this.sample() * maxValue);
}
var num = maxValue - minValue;
if (num <= MBIG) {
return Math.floor(this.sample() * num + minValue);
}
return Math.floor(this[getSampleForLargeRange]() * num + minValue);
},
nextBytes: function nextBytes(buffer) {
for (var i = 0; i < buffer.length; i++) {
buffer[i] = Math.floor(this[internalSample]() % 256);
}
},
nextDouble: function nextDouble() {
// in doubles have precison of 15 / 16
var scale = this.sample().toString();
var slice = scale.substring(0, 16);
var last = scale[16];
var next = scale[17];
if (next >= 5) last++;
slice = slice + last.toString();
return parseFloat(slice);
},
sample: function sample() {
return this[internalSample]() * 4.6566128752458e-10;
}
};
Random.prototype[internalSample] = function () {
var num = this.inext,
num1 = this.inextp,
num2 = num + 1;
num = num2;
if (num2 >= 56) {
num = 1;
}
var num3 = num1 + 1;
num1 = num3;
if (num3 >= 56) {
num1 = 1;
}
var seedArray = this.seedArray[num] - this.seedArray[num1];
if (seedArray === MBIG) seedArray--;
if (seedArray < 0) {
seedArray = seedArray + MBIG;
}
this.seedArray[num] = seedArray;
this.inext = num;
this.inextp = num1;
return seedArray;
};
Random.prototype[getSampleForLargeRange] = function () {
var num = this[internalSample]();
if (this[internalSample]() % 2 == 0 ? true : false) {
num = -num;
}
return (num + MBIG) / 4294967293;
};
module.exports = exports["default"];