我一直在阅读有关 XorShift PRNG 的信息,尤其是论文 here
一个人 here指出
The number lies in the range [1, 2**64). Note that it will NEVER be 0.
查看有意义的代码:
uint64_t x;
uint64_t next(void) {
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
return x * UINT64_C(2685821657736338717);
}
如果 x
为零,则下一个数字也将为零。但这不会降低它的用处吗?通常的使用模式类似于 min + rand() % (max - min)
或者如果您只需要 int
则将 64 位转换为 32 位。但是,如果永远不会返回 0
,那可能是一个严重的问题。此外,这些位不是 0
或 1
的概率与显然 0
丢失的概率相同,因此为零或可能性稍低。我什至在维基百科上找不到任何提及,所以我错过了什么吗?
那么在给定范围内从 XorShift64* 生成随机、均匀分布的数字的好方法是什么?
最佳答案
简短回答:不,它不能返回零。
根据Numeric Recipes “它产生一个完整的 2^64-1
[...] 缺失值为零”。
本质上,这些移位值已被仔细选择以生成非常长的序列(完全可能是一个没有零),因此可以确保生成每个数字。零确实是这个生成器的固定点,因此它产生 2 个序列:零和另一个包含所有其他数字。
因此 IMO 对于足够小的范围 max-min
足以使函数 (next() - 1) % (max - min) + min
或即使完全省略减法,因为模将返回零。
如果想要更好的质量均匀分布,应该使用“常规”方法,使用 next()
作为范围为 [1, 2^64)
的基础生成器/p>
关于c++ - XorShift 可以返回零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44753463/