我已经将JavaScript(由kotarou3)的LCG算法移植到Java。原始代码声明如果没有参数传递给函数,它应该在[0,1]中返回一个实数,就像Math.random()一样。但是,我的实现偶尔会在-1和0之间返回负数。
代码:
private int[] startingSeed = new int[]{(int) Math.floor(Math.random() * 0x10000),
(int) Math.floor(Math.random() * 0x10000),
(int) Math.floor(Math.random() * 0x10000),
(int) Math.floor(Math.random() * 0x10000)};
private int[] seed = new int[4];
public double random() {
this.seed = this.nextFrame();
double result = (this.seed[0] << 16 >>> 0) + this.seed[1];
result = result / 0x100000000L;
return result;
}
public int[] nextFrame() {
int[] seed = this.seed;
int n = 1;
for(int frame = 0; frame < n; ++frame) {
int[] a = new int[]{0x5D58, 0x8B65, 0x6C07, 0x8965};
int[] c = new int[]{0, 0, 0x26, 0x9EC3};
int[] nextSeed = new int[]{0, 0, 0, 0};
int carry = 0;
for (int cN = seed.length - 1; cN >= 0; --cN) {
nextSeed[cN] = carry;
carry = 0;
int aN = seed.length - 1;
int seedN = cN;
for(; seedN < seed.length; --aN, ++seedN) {
int nextWord = a[aN] * seed[seedN];
carry += nextWord >>> 16;
nextSeed[cN] += nextWord & 0xFFFF;
}
nextSeed[cN] += c[cN];
carry += nextSeed[cN] >>> 16;
nextSeed[cN] &= 0xFFFF;
}
seed = nextSeed;
}
return seed;
}
原始代码几乎相同,只有数据类型int
和double
为var
,但算法保持不变。