Skip to content

Instantly share code, notes, and snippets.

@jhamberg
Created October 31, 2019 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhamberg/eb693be32c2318e174c8a805c39bdbd0 to your computer and use it in GitHub Desktop.
Save jhamberg/eb693be32c2318e174c8a805c39bdbd0 to your computer and use it in GitHub Desktop.
Functional RNG in Javascript using LCG like Java's Random
function* Random(random) {
const m = [0xe66d, 0xdeec, 0x005];
let seed = [
((random) & 0xffff) ^ m[0],
((random / 2**16) & 0xffff) ^ m[1],
((random / 2**32) & 0xffff) ^ m[2]
];
function next(bits) {
let carry = 0xb;
let r = [];
r[0] = (seed[0] * m[0]) + carry;
carry = r[0] >>> 16;
r[0] &= 0xffff;
r[1] = (seed[1] * m[0] + seed[0] * m[1]) + carry;
carry = r[1] >>> 16;
r[1] &= 0xffff;
r[2] = (seed[2] * m[0] + seed[1] * m[1] + seed[0] * m[2]) + carry;
r[2] &= 0xffff;
seed = r;
return (seed[2] * 2**16 + seed[1]) >>> (32 - bits);
}
while (true) {
yield (2**27 * next(26) + next(27)) / 2**53;
}
};
@jhamberg
Copy link
Author

The LCG parameter 0x5DEECE66D used in Java is a composite 7 x 443 x 739 x 11003 = 25214903917 passing the Marsaglia's diehard test.

Basic usage:

const random = Random(123);
console.log(random.next()); // 0.7231742029971469
console.log(random.next()); // 0.9908988967772393
console.log(random.next()); // 0.25329310557439133

Advanced usage (using Immutable):

const { Seq } = require("immutable");

const random = Random(123);
const ten = Seq(random).take(10);
console.log(ten.toArray());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment