std :: normal_distribution <double>导致错误的命令窗口与Linux?

任何人来访问这个问题? 每1实现不需要产生相同的数据。 在实践中呢 – arm,x86,free和commercial编译器在STL实现方面有很多不同吗?

// g++ --std=c++11 -oa minimal.cpp && ./a #include <iostream> #include <random> using namespace std; int main() { std::mt19937_64 gen; gen.seed(17); cout << "\nNormal\n"; normal_distribution<double> distr1; for (int i = 0; i < 2; i++) { double delay = distr1(gen); printf(" Value = %15.15g\n", delay); } return(0); } /* Results (1) gcc-4.8.0 linux 64b version result Normal Value = 1.03167351251536 Value = 1.21967569130525 (2) Microsoft Visual Studio Community 2015 Version 14.0.23107.0 D14REL or Microsoft Visual Studio Professional 2012 Version 11.0.60610.01 Update 3 Normal Value = 1.21967569130525 Value = 1.03167351251536 // same values in wrong (different) order */ 

我可以理解在某些特殊的硬件平台上使用不同的algorithm来生成发生器或发行版,但是这种差异更像是一个bug。

以下是我用来诊断差异的更多代码,并解决它的不同之处: – 在win和linux上的生成器和统一分配匹配。 – 除了成对的顺序之外,正态分布在数字上是匹配的

 // g++ --std=c++11 -oa workaround.cpp && ./a #include <iostream> #include <random> #include <stack> using namespace std; typedef std::mt19937_64 RandGenLowType; // Helper wrapper - it did confirm that the differences // do NOT come from the generator class RandGenType : public RandGenLowType { public: result_type operator()() { result_type val = RandGenLowType::operator()(); printf(" Gen pulled %20llu\n", val); return(val); } }; typedef normal_distribution<double> NormalDistrLowType; // Workaround wrapper to swap the output data stream pairwise class NormalDistrType : NormalDistrLowType { public: result_type operator()(RandGenType &pGen) { // Keep single flow (used variables, includes) same for all platforms if (win64WaStack.empty()) { win64WaStack.push(NormalDistrLowType::operator()(pGen)); #ifdef _MSC_VER win64WaStack.push(NormalDistrLowType::operator()(pGen)); #endif } result_type lResult = win64WaStack.top(); win64WaStack.pop(); return(lResult); } private: std::stack<result_type> win64WaStack; }; int main() { RandGenType gen; gen.seed(17); // No platform issue, no workaround used cout << "\nUniform\n"; uniform_real_distribution<double> distr; for (int i = 0; i < 4; i++) { double delay = distr(gen); printf(" Delay = %15.15g\n", delay); } // Requires the workaround #ifdef _MSC_VER cout << "Workaround code is active, swapping the output stream pairwise\n"; #endif cout << "\nNormal\n"; //normal_distribution<float> distr1; NormalDistrType distr1; for (int i = 0; i < 10; i++) { double delay = distr1(gen); printf(" Value = %15.15g\n", delay); } return(0); } 

Solutions Collecting From Web of "std :: normal_distribution <double>导致错误的命令窗口与Linux?"

生成正态分布随机数的几种常见方法,例如Box-Muller变换和Marsaglia极坐标法 ,一次生成两个随机数。 使用这些方法之一的分发对象将生成两个随机数,返回其中一个,并在下一次调用时保存另一个。

当然,哪一个被返回,哪一个被存储,完全取决于图书馆作者。 它看起来像libstdc ++和MSVC使用相同的算法,但碰巧选择不同。