我正在尝试在Java中实现xorshift random number algorithm from Wikipedia。它在C中有一个带有无符号长整数的例子。鉴于Java没有无符号数,我如何摆脱下面代码中的Math.abs
?
我只想要正数。
private static long x = 0;
private static long y = 0;
private static long z = 0;
private static long w = 0;
private static long xorShiftRandom() {
while ((x | y | z | w) == 0) {
Random rand = new Random();
x = rand.nextLong();
y = rand.nextLong();
z = rand.nextLong();
w = rand.nextLong();
}
long t = x ^ (x << 11);
x = y;
y = z;
z = w;
return w = Math.abs(w ^ (w >>> 19) ^ (t ^ (t >>> 8)));
}
答案 0 :(得分:3)
Java中没有unsigned,所以这不是一个选项。我认为实际上你的问题是在打印它们时,它们显示为负面。您可以使用十六进制格式(Long.toHexString()
)来显示无符号值。或者你可以使用像BigInteger
这样的更大的持有者来获得无符号的十进制表示。
编辑:如果Java中的long
从Long.MIN_VALUE
生成到Long.MAX_VALUE
,那么随机数生成器应该在整个域中生成数字,而不是只有正数(仅为域的一半)。
答案 1 :(得分:2)
请注意,您的算法完全错误。维基百科的示例使用32位变量。它是一个128位状态生成器,您正在使用的移位将为这样的生成器提供最大周期 ONLY 。
DSI实用程序(http://dsiutils.di.unimi.it/)包含xorshift * / xorshift + generator的几种实现,它们是xorshift的64位变体,不会出现线性伪像。我建议你从那里开始。
答案 2 :(得分:1)
您可以将函数的最后一行更改为:
w = (w ^ (w >>> 19) ^ (t ^ (t >>> 8)));
return w & 0x7fffffffffffffffL;
这仍将生成所有64位,但仅报告其中的63位。
顺便说一句,您不应该通过多次调用方法来生成新的Random
对象。将Random rand = new Random();
移至您声明x
,y
,z
和w
的位置,并将其设为private static
。尽管在第一次调用方法后几乎从不触发循环,但多次实例化PRNG通常是一个坏主意。