随机数生成器比高数更频繁地生成低数 C++

Random number generator generating low numbers more frequently than high numbers C++

所以,我制作了一个模拟事物的程序,在其中我注意到 c++ 函数 运行d() 似乎过于频繁地生成低数字,所以我尝试对其进行测试。

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <cstdlib>
#include <time.h>
#include <cfloat>
#include <iomanip> 

using namespace std;

int main(){
    srand(time(NULL));
   
    int qwerty=0;
    for(int i=0; i<10000000;i++){
        if(rand()%10000<2800){
            qwerty++;
        }
    }
    cout << qwerty << endl;
    return 0;
}

如果我 运行 文件中有这个“for tester”,我会得到一个接近 3400000 或 34% 的数字,这接近我在真实程序中看到的 34% ,问题是输出应该接近 2800000 或 28%。

然后我尝试 运行 在一个新项目(我在这里写的一样)上 运行 这个“测试人员”,其中只有库和 s运行d(time(NULL))现在,相同的输出。

然后我尝试将此文件复制到在线编译器中,这次我得到的不是 3400000,而是正确的数字 2800000。

我找不到为什么会这样,有人知道吗?

附加信息: 我将 dev-c++ 作为 IDE 与 TDM-GCC 4.9.2 64 位版本和 ISO C++11 一起使用,如果我将我的计算机生成的可执行文件和 运行 它放在另一台计算机中我得到相同的 34% 结果,Windows 10 是操作系统。如果我使用不同的数字,也会出现此问题。

这是 % 的一个众所周知的问题,并且在极少数情况下不是 rand 的错。

为了示例考虑 RAND_MAX == 2。进一步假设 rand() 是完全均匀的。然后你得到数字 012。现在看看这个:

 int x = rand() % 2;

如果兰特的分配是

rand()   P
0       1/3 33.33333 %
1       1/3 33.33333 %
2       1/3 33.33333 %

那么x的结果分布是:

x       P
0       2/3 66.66666 % 
1       1/3 33.33333 %

解决方案:使用<random>中提供的工具。

对于开区间[0, 32767]内均匀分布的随机变量E mod(E, 10000) < 2800 的概率约为 34%。直觉上,您可以将 mod(E, 10000) < 2800 视为支持 [30000, 32767] 范围内的数字桶:桶 modulo 10000 总是小于 2800。所以有将结果推到 28% 以上的效果。

这就是您在这里观察到的行为。

它不是随机生成器质量的函数,但如果您使用具有更大周期性的均匀生成器,您会得到更好的结果。从 C++ 标准库中使用 rand() 是 ill-advised,因为该标准对功能要求过于宽松,无法移植。来自 C++11 的 <random> 会给你带来的麻烦要少得多:你也可以避免显式 %