C++ - 円周率計算(モンテカルロ法)!
Updated:
最近 C++ (GNU版) も弄っているので、練習がてら円周率を計算するプログラムを作成しました。
と言っても、モンテカルロ法です。 モンテカルロ法、その他円周率の計算等については各自調べてください。
記録
0. 前提条件
作業した環境は Cygwin 1.7.15 です。 使用したコンパイラは g++ (GCC) 4.7.1 です。
1. C++ ソース作成
今回作成した C++ ソースは以下の通りです。 C++ なのでオブジェクト指向な作りにしています。 また、プロット回数を増やしすぎると当然ながらオーバーフローします。 【 ファイル名: PiMontecarlo.cpp 】
#include <cstdlib> // for rand()
#include <iostream> // for cout
#include <math.h> // for pow()
#include <stdio.h>
using namespace std;
/**
* 計算クラス
*/
class Calc
{
// 各種宣言
int iNum; // プロット回数宣言
double x, y; // x, y 座標
int i; // ループ処理用インデックス
int iIn; // 1/4 円に入った回数
double pi; // 円周率
public:
// コンストラクタ宣言
Calc();
// 円周率計算関数宣言
void calcPi();
// 円周率取得関数宣言
double getPi();
};
/**
* コンストラクタ
*/
Calc::Calc()
{
// 初期化
iNum = pow(10, 5); // プロット回数
iIn = 0; // 1/4 円に入った回数
// プロット回数出力
cout << "プロット回数 = " << iNum << endl;
}
/**
* 円周率計算
*/
void Calc::calcPi()
{
// 指定したプロット回数分ループ
for (i = 0; i < iNum; i++) {
// random() を RAND_MAX で割ることで 0 から 1 の乱数を発生
x = random() / (double)RAND_MAX;
y = random() / (double)RAND_MAX;
// 原点から (x, y) の距離が 1 以下なら円内なのでカウント
if (x * x + y * y <= 1) {
iIn++;
}
}
// 上記は 1/4 円に入った回数なので、
// 円周率を求めるには 4 倍して、総プロット回数で割る
pi = 4 * iIn / (double)iNum;
}
/**
* 円周率取得
*/
double Calc::getPi()
{
return pi;
}
/**
* メイン処理
*/
int main()
{
// 円周率計算
Calc objCalc;
objCalc.calcPi();
// 円周率取得
double pi = objCalc.getPi();
// 結果出力
cout << "モンテカルロ法 = " << pi << endl;
// 比較のため、math.h で定義されている円周率を出力
cout << "math.h = " << M_PI << endl;
return 0;
}
2. コンパイル
以下のコマンドでコンパイルします。
$ g++ PiMontecarlo.cpp -o PiMontecarlo.exe
何も出力されなければ成功です。
3. 実行
実行します。
$ ./PiMontecarlo.exe
プロット回数 = 100000
モンテカルロ法 = 3.14152
math.h = 3.14159
やっぱり、C/C++ もおもしろいですね。 機械語・アセンブラに近い高水準言語ならではのおもしろさがあります。 生産性は最近の高水準言語と比べると劣りますが。。。
以上。
Comments