我正在整理一个内部“每个开发人员都应该知道”的 wiki 页面。
我看到很多关于rand() % N
,但没有一个网页可以解释这一切。
例如,我很好奇这个问题是否仅特定于 C 和 Linux,或者是否也适用于 Windows、C++。 Java、.Net、Python、Perl。
请帮我查清真相。另外,这些数字的非随机性到底有多大?谢谢你!
我没有可供您参考的网页,但我可能有一个“信封背面”的解释会有所帮助。简单随机数生成器的工作方式是按照以下步骤操作
- 使用最后生成的数字
n
或种子号。
- 将该数字乘以一个特殊的大数
- 添加另一个特殊的大数
- 将其除以第三个特殊大数并丢弃余数
- 返回结果
现在,如果您考虑除第 4 步之外的所有步骤中发生的情况,那么您正在执行的操作中,只有较低位可以更改结果的较低位。将 1001 和 100...00001 相加将以 ...02 结尾(哈,虽然我说的是基数 2,但实际上这些数字是基数 12 咯咯笑。)无论计算的高端是什么。同样,当你相乘时,无论如何它都会以 1 结尾。
在高端也存在类似的问题,十亿乘以十亿总是会主导数百位凋零数的贡献。这表明中间是好事发生的地方。许多位在这里相互作用——高、中、低。
这就是除法步骤的目的,它切断了结果的底部部分,那里没有太多的交互。顶部块通常不会被截断,因为当乘法不再适合机器字时,计算机会丢弃高位。
最后,尽管截断点有些任意,你可能比设计算法的人更挑剔,但仍然会截断更多位。
对于你的问题,他们可能有多糟糕,他们可能真的很糟糕。看到这一点的最简单方法是将单个数字分组为元组并绘制它们的图表。所以如果你有随机数a, b, c, d, ...
graph (a,b), (c,d), ...
并查看结果。这被称为频谱测试,兰德完美地通过了它。这个我有一个尝试的链接http://random.mat.sbg.ac.at/results/karl/spectraltest/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)