C rand() 略有偏差

C rand() slightly biased

我正在使用标准 c 库中的 rand() 函数为 Monte Carlo 模拟生成 0 到 1 范围内的数字:

(double)rand()/RAND_MAX

但我注意到结果略有偏差。我检查了生成数字的平均值,它略低于预期的 0.5。

我读到 rand() 是有模数偏差的,但我在这里没有使用模数。有没有更精确的方法来生成 1 和 0 之间的数字?

编辑: 我对 Prngs 还很陌生,所以我不知道有些 prngs 不是线程安全的。我应该提到我使用了 rand() 多线程。 无论如何,您的回答帮助我找到了更快且线程安全的 rng。

这取决于您的 C 实现。有些 rand 的实现质量高于其他。也许使用 arc4random,或其他一些基于加密的 PRNG。

我个人最喜欢的是xoroshiro。它通过了大多数伪随机性测试,而且速度非常快,比 rand().

快得多

当然,在典型情况下 rand() 是出了名的糟糕 PRNG。 (在我的系统上,man rand 打印“rand, rand_r, srand, sranddev -- bad random number generator”。)

rand 对某些事情来说往往很好,但我认为人们普遍认为它对于像样的蒙特卡罗模拟来说永远不够好。撇开它的分布不谈,它的周期往往不够长。 (典型的实现保留约 32 位状态,因此它们在 43 亿个样本后开始重复。)

话虽如此,(double)rand()/RAND_MAX 在我的机器上对我来说平均为 0.5 - 准确地说,我在 1,000,000,000 个样本后得到 0.500004。我怀疑您的系统的实现可能被破坏了——突然想到的一种可能性是它错误地发出了 0 到 RAND_MAX-1 范围内的数字。您可以尝试平均 rand()/(RAND_MAX-1.) 看看会发生什么。

(ObIdleOpinionating:我希望系统能更好地实现 rand(),而不是告诉你不要使用它并以不同的非标准名称为你提供更好的 PRNG。但我希望什么并不重要,因为每个人似乎都在做一个蹩脚的 rand() 和一个更好但非标准的替代命名版本。)