/* * 円周率を計算する関数(ガウス=ルジャンドル法) * 引数 printProgress は、trueなら計算進行状況を表示する * * ※varfloat型は、多倍長精度の浮動小数点を扱う型 */ varfloat pi( bool printProgress ){ int start = time(); // 処理開始時間 /* * アルゴリズムで使う変数 */ varfloat value = 0.0vf; varfloat a = 1.0vf; varfloat b; varfloat aStock = 0.0vf; varfloat bStock = 0.0vf; varfloat c = 0.25vf; varfloat d = 1.0vf; /* * bの初期値を1/√2 = √0.5に設定 * 2個目の引数の即値は、収束初期値で、結果に近い値 */ b = sqrt( 0.5vf, 0.7071067811865475vf ); /* * ガウス=ルジャンドル法による * 円周率の収束アルゴリズム */ int loopCount = 0; while( a != aStock && b != bStock ){ aStock = a; bStock = b; a = ( aStock + bStock )*0.5vf; // 平方根の計算、収束高速化のため前ループの結果からスタート b = sqrt( aStock*bStock, b ); c = c - d*( a - aStock )*( a - aStock ); d = 2.0vf*d; // 計算進行状況を表示 if( printProgress ){ // 現在までの計算所要時間 float sec = millisecond( time() - start ) / 1000.0; loopCount++; println( loopCount + " ループ完了 / " + sec + " SEC" ); } } value = (a+b)*(a+b) / (4.0vf*c); return value; }