为什么使用 rand() 会有更高数字的概率
Why is there a probability of higher numbers using rand()
我猜很奇怪的问题。这是出于好奇。
使用 rand() 函数,如果我们在 1-10 之间设置参数,然后我在我的机器 UNIX 操作系统上运行了几次测试,更具体地说是 Ubuntu。我的结果总是显示更高的数字(大于 5)更有可能返回。这似乎一点都不像是随机的。
我还阅读了模数,它指出使用模数运算,我们形成了某种偏差。
请注意,此模运算不会在跨度中生成均匀分布的随机数(因为在大多数情况下,此操作会使较小的数字更有可能)。
为什么?它还说较低的数字变得更有可能,但是我得到更多的数字
如何测试偏差
系统上的rand()
生成器(glibc 中的生成器)有问题,但过度偏差不在其中。 假设您使用以下代码在给定范围内生成随机数。
int random_int(int min, int max)
{
return min + rand() % (max - min + 1);
}
我们不要假设你播种数字。
int main(int argc, char **argv)
{
int histo[10];
for (int i = 0; i < 10; i++)
histo[i] = 0;
for (int i = 0; i < 10000; i++)
histo[random_int(1, 10) - 1]++;
for (int i = 0; i < 10; i++)
printf("%dn", histo[i]);
}
这将为我们提供 10,000 个样本,这很小但可行。 我得到以下结果。 如果您使用的是相同版本的 glibc,您将获得完全相同的版本。
10539801002959100994810361041987985
我们期望箱服从二项分布,给定一个无偏生成器。 对于 10,000 个样本,我们预计每个箱的方差为 Np(1-p) 或 900,这给出的标准差正好为 30。 我们的样本方差为 1105。 现在,我不会在这里做任何严格的事情......我要假装二项分布是正态的...我只是要做一个简单的卡方检验。 结果为 p=0.2。 不完全是诅咒。
因此,如果您想测试随机数生成器,请记住事后进行数学运算以解释测试结果。
模偏置
模偏差实际上增加了较低数字的概率,而不是较高数字的概率。 对于这样的范围(1..10),偏差非常小,因为对于glibc RAND_MAX
是231-1,这使得小数字的概率增加了大约1/2亿。 您需要执行大量测试才能暴露模偏差。
不鼓励模的主要原因是因为常见rand()
实现的低位显示出较差的独立性。 当然,您也不应该使用此技术来生成大范围。
建议
如果你真的想测试你的随机数生成器,我建议看看Marsaglia后期的"顽固"测试。 如果你只想要一个好的随机数生成器,你可以使用 arc4random, Mersenne Twister, or /dev/urandom
. 根据您是开发加密应用程序还是使用蒙特卡罗模拟结果,您的选择会有所不同。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 在 C/C++ 中乘以低数字(相对于高数字)是否更快?
- 如何计算在重复数字之前 x 必须在 (x * y) % z 中有多高
- 在Windows 10中,将Clocks_per_sec重新定义为更高的数字
- 三个数字之间的 C++ 相加两个更高的数字,没有循环和数组
- 2命令行参数中的数字数字仅被视为一个数字
- 如何验证输入仅是数字数字
- 如何在较高和较低数字的阵列中适应搜索算法(3N / 2)-2
- 为什么将高数字传递给递归功能会使我的控制台停止响应
- C++余数以较高的数字返回 7
- C++不会根据需要将数字/数字插入向量
- 为什么使用 rand() 会有更高数字的概率
- 数字/数字识别手写
- 从字符串中提取数字/数字范围的复杂算法
- 具有一个零位的下一个更高的数字
- 如何循环矩阵使对角线上的数字具有很高的优先级
- 数字数字的排列
- 快速排序不排序高范围的数字
- 用C++中的高数字进行计算