我想在Java,Python和JavaScript中实现XorShift PRNG.给定相同的种子,不同的实现必须生成完全相同的序列.到目前为止,我还没能做到这一点.
我在Java中的实现
在Java中使用以下XorShift PRNG实现(其中x
是一个long
字段):
public long randomLong() { x ^= (x << 21); x ^= (x >>> 35); x ^= (x << 4); return x; }
如果我播种x
到1,前四个调用randomLong()
将生成:
35651601 1130297953386881 -9204155794254196429 144132848981442561
我在Python中的实现
无论有没有numpy我都尝试过.下面是使用numpy的版本.
def randomLong(self): self.x ^= np.left_shift(self.x, 21) self.x ^= np.right_shift(self.x, 35) self.x ^= np.left_shift(self.x, 4) return self.x
使用相同的种子,Python函数将生成:
35651601 1130297953386881 -9204155787274874573 # different 143006948545953793 # different
我的JavaScript实现
我还没有尝试过,因为JavaScript的唯一数字类型似乎是基于IEEE 754的双打,这开启了不同的蠕虫病毒.
我认为原因是什么
Java和Python有不同的数字类型.Java有32位和64位整数,而Python有很时髦的大型int.
看起来移位运算符具有不同的语义.例如,在Java中有逻辑和算术移位,而在Python中只有一种移位(逻辑?).
问题
我很高兴能得到一个答案,让我用这三种语言写一个PRNG,而且速度很快.它不一定非常好.我已经考虑将C libs实现移植到其他语言,虽然它不是很好.
我可以修复上面的实现,以便它们工作吗?
我应该切换到另一个更容易在prog.langs上实现的PRNG函数吗?
我已经读过有人建议使用Python的java.util.Random类的SO.我不想要这个,因为我也需要JavaScript中的函数,我不知道这个包存在于那里.
我很高兴能得到一个答案,让我用这三种语言写一个PRNG,而且速度很快.它不一定非常好.
您可以用3种语言实现32位线性同余生成器.
蟒蛇:
seed = 0 for i in range(10): seed = (seed * 1664525 + 1013904223) & 0xFFFFFFFF print(seed)
Java的:
int seed = 0; for (int i = 0; i < 10; i++) { seed = seed * 1664525 + 1013904223; System.out.println(seed & 0xFFFFFFFFL); }
JavaScript的:
var seed = 0; for (var i = 0; i < 10; i++) { // The intermediate result fits in 52 bits, so no overflow seed = (seed * 1664525 + 1013904223) | 0; console.log(seed >>> 0); }
输出:
1013904223 1196435762 3519870697 2868466484 1649599747 2670642822 1476291629 2748932008 2180890343 2498801434
请注意,在所有3种语言中,每次迭代都会打印一个无符号的32位整数.