c++ - XorShift 可以返回零吗?

标签 c++ random

我一直在阅读有关 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,那可能是一个严重的问题。此外,这些位不是 01 的概率与显然 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/

相关文章:

c++ - 定位因整数除法导致的数值错误

c++ - 检测到内存泄漏

带分数的概率的 PHP 数组

algorithm - 使用 Rand3() 的随机生成器 Rand9()

c++ - 为什么取消引用多态指针将获得指针的类型而不是对象的类型?

c++ - 从 ECDSA 公钥生成比特币地址

c++ - getline() 从 csv 携带 '\n'

python - 在python中生成分类数据集

java - 比较用户输入之间随机生成的数字

random - 如何从 CouchDB 加载随机文档(高效且公平)?