我最近剛剛發現了一個C++的bug /特性,我不能完全理解,並希望有人在這裏有更好的C++知識可以指向正確的方向。由於輸出的不同蒙特卡羅積分結果
下面您會發現我嘗試使用蒙特卡羅積分找出高斯曲線下的區域。配方是:
- 生成大量的正態分佈的隨機變量(平均值爲零,標準差爲1)。
- 正方形這些數字。
- 取所有廣場的平均值。平均值將是對曲線下面積的非常接近的估計(在高斯情況下,它是1.0)。
下面的代碼包含兩個簡單的功能:rand_uni
,它返回一個隨機變量,零和一,和rand_norm
之間均勻分佈的,這是一個(比較差,但「足夠好政府工作」)逼近的正態分佈隨機變量。
main
貫穿循環10億次,每次調用rand_norm
,將其與pow
平方並添加到累加變量中。在此循環之後,累計結果僅以運行次數除以Result=<SOME NUMBER>
打印到終端。
問題在於下面代碼的非常古怪的行爲:當每個生成的隨機變量打印到cout
(是的,十億次),那麼最終結果是正確的,無論使用的是哪種編譯器(1.0015,這很漂亮接近,我想要的)。如果我沒有在每次循環迭代中打印隨機變量,我會在gcc
下獲得inf
,在clang
下獲得448314。坦率地說,這只是令人難以置信的頭腦,因爲這是我與C++的第一次碰撞,我真的不知道,問題可能是什麼:pow
是什麼東西? cout
行爲怪異嗎?
任何提示將不勝感激!
來源
// Monte Carlo integration of the Gaussian curve
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
enum {
no_of_runs = 1000000
};
// uniform random variable
double rand_uni() {
return ((double) rand()/(RAND_MAX));
};
// approximation of a normaly distributed random variable
double rand_norm() {
double result;
for(int i=12; i > 0; --i) {
result += rand_uni();
}
return result - 6;
};
int main(const int argc,
const char** argv) {
double result = 0;
double x;
for (long i=no_of_runs; i > 0; --i) {
x = pow(rand_norm(), 2);
#ifdef DO_THE_WEIRD_THING
cout << x << endl; // MAGIC?!
#endif
result += x;
}
// Prints the end result
cout << "Result="
<< result/no_of_runs
<< endl << endl;
}
Makefile的
CLANG=clang++
GCC=g++
OUT=normal_mc
default: *.cpp
$(CLANG) -o $(OUT).clang.a *.cpp
$(CLANG) -o $(OUT).clang.b -DDO_THE_WEIRD_THING *.cpp
$(GCC) -o $(OUT).gcc.a *.cpp
$(GCC) -o $(OUT).gcc.b -DDO_THE_WEIRD_THING *.cpp
感謝您的提示和解釋! – jst