Skip to content

Instantly share code, notes, and snippets.

@raybellis
Last active March 15, 2022 21:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save raybellis/4c15a1746724be7bd03964e9d03e0c75 to your computer and use it in GitHub Desktop.
Save raybellis/4c15a1746724be7bd03964e9d03e0c75 to your computer and use it in GitHub Desktop.
Emulation of java.util.Random in Javascript
class UInt48 {
constructor(n) {
if (n instanceof UInt48) {
Object.assign(this, n);
} else if (typeof n === 'number') {
let w0 = n & 0xffff;
n /= 0x10000;
let w1 = n & 0xffff;
n /= 0x10000;
let w2 = n & 0xffff;
Object.assign(this, { w2, w1, w0 });
}
}
norm() {
if (this.w0 >= 0x10000) {
let carry = Math.floor(this.w0 / 0x10000);
this.w1 += carry;
this.w0 &= 0xffff;
}
if (this.w1 >= 0x10000) {
let carry = Math.floor(this.w1 / 0x10000);
this.w2 += carry;
this.w1 &= 0xffff;
}
this.w2 &= 0xffff;
return this;
}
add(n) {
let tmp = new UInt48(this);
tmp.w0 += n.w0;
tmp.w1 += n.w1;
tmp.w2 += n.w2;
return tmp.norm();
}
xor(n) {
let tmp = new UInt48(this);
tmp.w2 ^= n.w2;
tmp.w1 ^= n.w1;
tmp.w0 ^= n.w0;
return tmp;
}
mul(n) {
let tmp1 = new UInt48(n);
tmp1.w2 = tmp1.w2 * this.w0;
tmp1.w1 = tmp1.w1 * this.w0;
tmp1.w0 = tmp1.w0 * this.w0;
tmp1.norm();
let tmp2 = new UInt48(n);
tmp2.w2 = tmp2.w1 * this.w1;
tmp2.w1 = tmp2.w0 * this.w1;
tmp2.w0 = 0;
tmp2.norm();
let tmp3 = new UInt48(n);
tmp3.w2 = tmp3.w0 * this.w2;
tmp3.w1 = 0;
tmp3.w0 = 0;
tmp3.norm();
return tmp3.add(tmp2).add(tmp1);
}
valueOf() {
return 0x10000 * (0x10000 * this.w2 + this.w1) + this.w0;
}
}
class Random {
constructor(seed) {
const mul = new UInt48(0x5deece66d);
const add = new UInt48(0xb);
if (seed === undefined) {
seed = Math.floor(Math.random() * 0x1000000000000);
}
this.setSeed = (n) => {
seed = new UInt48(n).xor(mul);
}
this.setSeed(seed);
this.next = (bits) => {
seed = seed.mul(mul).add(add);
// return ~~(seed / Math.pow(2, 48 - bits));
return (seed / 0x10000) >> (32 - bits);
}
this.nextInt = () => this.next(32);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment