为什么GCC和MSVC std :: normal_distribution不同?

Duc*_*een 11 c++ gcc visual-studio visual-c++ c++11

我有一个简单的代码示例:

#include <iostream>
#include <random>
using namespace std;
int main() {
    minstd_rand0 gen(1);
    uniform_real_distribution<double> dist(0.0, 1.0);
    for(int i = 0; i < 10; ++i) {
        cout << "1 " << dist(gen) << endl;
    }

    normal_distribution<double> dist2(0.0, 1.0);
    minstd_rand0 gen2(1);
    for(int i = 0; i < 10; ++i) {
        cout << "2 " << dist2(gen2) << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在gccmsvc编译.我在std代码上得到了不同的结果!( 在此输入图像描述

那么为什么GCC和MSVC std::normal_distribution结果对于相同的种子和发生器是不同的,最重要的是,如何强制它们是相同的?

Nat*_*ica 6

与标准定义的PRN生成器不同,PRN生成器必须为同一种子生成相同的输出,标准不保留对于分布的任务.来自[rand.dist.general]/3

用于产生每个指定分布的算法是实现定义的.

所以在这种情况下即使分布必须具有密度函数的形式

在此输入图像描述

实现如何取决于他们.

获得可移植分发的唯一方法是自己编写一个或使用第三方库.


Joh*_*erg 5

这是有问题的,但遗憾的是,标准没有详细说明在构建(多个)随机分布的数字时使用的算法,并且有几个有效的替代方案,具有不同的好处.

26.6.8.5正态分布[rand.dist.norm] 26.6.8.5.1类模板normal_distribution [rand.dist.norm.normal]

normal_distribution随机数分布产生根据概率密度函数分布的随机数x

在此输入图像描述

参数μ和也称为该分布的均值和标准差.

生成正态分布数的最常用算法是Box-Muller,但即使使用该算法,也有选项和变量.

标准中甚至明确提到了自由:

26.6.8随机数分布类模板[rand.dist]...

3用于生成每个指定分布的算法是实现定义的.

这个的goto选项是随机增强

顺便说一下,正如@Hurkyl所指出的那样:似乎这两个实现实际上是相同的:例如,box-muller生成一对值,其中一个返回,一个被缓存.这两种实现的不同之处仅在于返回了哪些值.

此外,随机数引擎是完全指定的,并且将在实现之间给出相同的顺序,但是需要注意,因为不同的分布也可以消耗不同数量的随机数据以产生它们的结果,这将使引擎排除同步