area51
Version:
Experimental prototypes of alien things built in JavaScript. The bits may end up living in a different package.
140 lines (113 loc) • 3.46 kB
JavaScript
//https://android.googlesource.com/platform/libcore/+/184d077ac4e1e008b8ef8a4cf0af60c4d87cfccb/luni/src/main/java/java/util/Random.java
"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 _long = require("long");
var _long2 = _interopRequireDefault(_long);
var serialVersionUID = 3905348978240129500;
var multiplier = 25214903917;
var haveNextNextGaussian = (0, _es6SymbolJs2["default"])();
var nextNextGaussian = (0, _es6SymbolJs2["default"])();
var next = _es6SymbolJs2["default"]["for"]("next");
var seedBase = 0;
function castIntToByte(intValue) {
var arr = new ArrayBuffer(4);
var view = new DataView(arr);
view.setUint8(0, intValue, true);
return view.getInt8(0);
}
function Random(seed) {
this[next] = Random.prototype[next];
if (!seed) {
this.setSeed(new Date().getTime() + seedBase);
++seedBase;
} else {
this.setSeed(seed);
}
}
;
Random.prototype = {
nextBoolean: function nextBoolean() {
return this[next](1) != 0;
},
nextBytes: function nextBytes(buffer) {
var rand = 0,
count = 0,
loop = 0;
while (count < buffer.length) {
if (loop == 0) {
rand = this[next](32);
loop = 3;
} else {
loop--;
}
buffer[count++] = castIntToByte(rand);
rand = rand >> 8;
}
},
nextInt: function nextInt(maxValue) {
var next = _es6SymbolJs2["default"]["for"]("next");
if (arguments.length == 0) {
return this[next](32);
}
if (arguments.length == 1) {
var n = maxValue;
if ((n & -n) === n) {
// return (int) ( (n * (long)next(31)) >> 31 )
var next2 = _long2["default"].fromInt(this[next](31));
return next2.multiply(n).shiftRight(31).toInt();
}
var bits, val;
do {
bits = this[next](31);
val = bits % n;
} while (bits = val + (n - 1) < 0);
return val;
}
},
nextDouble: function nextDouble() {
// return ((((long) next(26) << 27) + next(27)) / (double) (1L << 53));
var long = _long2["default"].fromInt(this[next](26));
long = long.shiftLeft(27).add(this[next](27)).toNumber();
return long / 9007199254740992;
},
nextFloat: function nextFloat() {
// (next(24) / 16777216f);
return this[next](24) / 16777216;
},
nextGaussian: function nextGaussian() {
if (this[haveNextNextGaussian]) {
this[haveNextNextGaussian] = false;
return this[nextNextGaussian];
}
var v1, v2, s;
do {
v1 = 2 * this.nextDouble() - 1;
v2 = 2 * this.nextDouble() - 1;
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
var multiplier = Math.sqrt(-2 * Math.log(s) / s);
this[nextNextGaussian] = v2 * multiplier;
return v1 * multiplier;
},
nextLong: function nextLong() {
// ((long) next(32) << 32) + next(32);
return _long2["default"].fromInt(this[next](32)).shiftLeft(32).add(this[next](32));
},
setSeed: function setSeed(seed) {
seed = _long2["default"].fromString(seed.toString());
// 281474976710655 = (1L << 48 - 1)
this.seed = seed.xor(multiplier).and(281474976710655);
this[haveNextNextGaussian] = false;
}
};
Random.prototype[next] = function (bits) {
var seed = this.seed = this.seed.multiply(multiplier).add(11).and(281474976710655);
return seed.shiftRight(48 - bits).toInt();
};
module.exports = exports["default"];