xorshift128 +算法的真正定义是什么?

时间:2015-12-22 23:59:22

标签: c++ c algorithm random

我需要一个好的伪随机数发生器(PRNG),看起来当前的技术水平是xorshift128 + algoritm。不幸的是,我发现了2个不同的版本。维基百科上的那个:Xorshift显示为:

uint64_t s[2];

uint64_t xorshift128plus(void) {
    uint64_t x = s[0];
    uint64_t const y = s[1];
    s[0] = y;
    x ^= x << 23; // a
    s[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
    return s[1] + y;
}

这似乎足够直截了当。更重要的是,编辑日志似乎显示这个代码片段是由名为“Vigna”的用户添加的,该用户可能是“Sebastiano Vigna”,他是xorshift128 +:Further scramblings of Marsaglia’s xorshift generators论文的作者。不幸的是,该论文的实施略有不同:

uint64_t next(void) {
    uint64_t s1 = s[0];
    const uint64_t s0 = s[1];
    s[0] = s0;
    s1 ^= s1 << 23; // a
    s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
    return s[1] + s0;
}

除了一些不同的名称外,这两个片段除了最后两个班次外是相同的。在维基百科版本中,这些转变是17和26,而论文的转变是18和5。

有谁知道哪个是“正确的”算法?这有什么不同吗?这显然是一种相当广泛使用的算法 - 但使用的版本是什么?

1 个答案:

答案 0 :(得分:3)

感谢@Blastfurnace,似乎答案是根据算法作者的最新一组常量是:23,18和5.显然它并不重要,但那些理论上比他使用的初始数字集更好。 Sebastiano Vigna发表这些评论是为了回应news that the V8 Javascript engine正在转向使用此算法。

我正在使用的实现是:

uint64_t a = s[0];
uint64_t b = s[1];

s[0] = b;
a ^= a << 23;
a ^= a >> 18;
a ^= b;
a ^= b >>  5;
s[1] = a;

return a + b;