Xorshift在Java中随机

时间:2014-01-30 15:27:17

标签: java random

我正在尝试在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)));
}

3 个答案:

答案 0 :(得分:3)

Java中没有unsigned,所以这不是一个选项。我认为实际上你的问题是在打印它们时,它们显示为负面。您可以使用十六进制格式(Long.toHexString())来显示无符号值。或者你可以使用像BigInteger这样的更大的持有者来获得无符号的十进制表示。

编辑:如果Java中的longLong.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();移至您声明xyzw的位置,并将其设为private static。尽管在第一次调用方法后几乎从不触发循环,但多次实例化PRNG通常是一个坏主意。