在C++中使用统一实分布生成的随机数并不是真正均匀分布的

azi*_*ish 6 c++ random

我写了一个小代码,以确保我可以从一个非常广泛的范围获得随机数,例如.[0,10 ^ 36]因为我将在以后使用这些宽范围.

我的代码如下:

#include <iostream>
#include <cmath>
#include <random>
#include <chrono>

int main()
{   unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    double expo = pow(10,36);
    std::uniform_real_distribution<double> dist(0,expo);
    std::mt19937_64 rng(seed);
    for (int i=0; i<10; i++)
        std::cout << dist(rng) << std::endl;
    return 0;
}   
Run Code Online (Sandbox Code Playgroud)

以下是输出的示例:

6.75507e+035
4.01129e+035
6.85525e+035
8.85896e+035
3.1455e+035
3.04962e+035
5.48817e+035
3.54502e+035
2.24337e+035
2.23367e+035
Run Code Online (Sandbox Code Playgroud)

如您所见,随机数都非常接近给定区间的上端点.我尝试多次运行程序,也将10个数字增加到100,但随机数总是接近区间的上端点(指数为35,有时为34).

自从我使用以来std::uniform_real_distribution,我希望也有,有时也会有[0,1000]范围内的数字.我发现这不是一个统一的分布.这对我来说很重要,随机数不仅接近上端点,因为我稍后会在if语句中使用随机数:

if (random_number == 0)
    //do some operations
Run Code Online (Sandbox Code Playgroud)

并且上端点实际上将用作速率,其中发生某些事情.但似乎随机数有时候没有机会为零.

我不知道为什么会发生这种情况,并且非常感谢任何想法或帮助.

(Eclipse 4.4.1,Windows 7)

Ben*_*ley 15

如您所见,随机数都非常接近给定区间的上端点.

不,他们不是.这一个,例如:

2.23367e+035
Run Code Online (Sandbox Code Playgroud)

请注意,在该范围内[0, 1e36],子范围[1e35, 1e36]是子范围的9倍[0, 1e35],因此通过均匀分布,您可以期望看到这些数字的频率为9倍.你会看到指数为34的数字,但是指数任何较低的指数都会非常罕见.

  • 那就对了!我没想过......所以这意味着它真的是一个统一的分布.谢谢你,本杰明! (2认同)