ゆるゆるプログラミング

・円周率πを求める その1

円周率πを計算で求める方法を紹介します。

ここで紹介するアルゴリズムは、単位円を小さく分割した台形で近似し、それら台形の面積合計円周率πを求めるものです。

円の面積は、

 (半径×半径×円周率)

で求められるので、単位円の面積は、

 (1×1×円周率)=円周率π

となります。よって、単位円の面積の計算は、円周率を計算することと同じことです。

単位円の面積=円周率

ここからは、具体的な単位円の面積計算方法の説明です。

単位円の右上1/4を台形(一番上は三角形)に分割します。このとき台形の高さを全て同じにします。以下の例は、単位円の右上1/4を2つの台形に分割した例です。オレンジ色で塗りつぶされている部分が台形の範囲です。

単位円の分割(y方向に2分割)

以下の例は、単位円の右上1/4を4つの台形に分割した例です。

単位円の分割(y方向に4分割)

このオレンジ色で塗られた部分の面積を計算し、それを4倍した値を円周率πとします。

分割する数を増やすとオレンジ色で塗られた部分の形が、単位円に近づいていきます。そして、それは台形の面積合計値が、単位円の1/4の面積に近づくことを意味しています。

以下は、円周率πを計算するJavaソースコードです。

CalcPI1.java ← クリックしてダウンロードページに移動
001:    public class CalcPI1 {
002:    	// πを計算するメソッド
003:    	public static double getPI_1( int yn )
004:    	{
005:    		double upperbase;	// 台形の上底
006:    		double lowerbase;	// 台形の下底
007:    		double height;		// 台形の高さ
008:    		double lowery;		// 台形の下底の座標
009:    		double area;		// 円の面積
010:    		double aread;		// 台形の面積
011:    
012:    		// 台形の高さ(円の半径をynで割る)
013:    		height = 1.0 / (double)yn;
014:    
015:    		// 上底の初期値
016:    		upperbase = 0.0;
017:    
018:    		// 下底のy座標の初期値
019:    		lowery = 1.0 - height;
020:    
021:    		// 計算開始
022:    		area = 0.0;
023:    		for ( int i = 0; i < yn; ++ i ) {
024:    			// 下底の計算
025:    			lowerbase = Math.sqrt( 1.0 - lowery * lowery );
026:    
027:    			// 台形の面積計算
028:    			aread = ( upperbase + lowerbase ) * height / 2.0;
029:    
030:    			// 円の面積に台形の面積を足す
031:    			area += aread;
032:    
033:    			// 下底を上底に代入
034:    			upperbase = lowerbase;
035:    
036:    			// 下底のy座標からheightを引く
037:    			lowery -= height;
038:    		}
039:    
040:    		// 1/4円の面積を4倍
041:    		area = area * 4.0;
042:    
043:    		// 結果を戻す
044:    		return area;
045:    	}
046:    
047:    
048:    	public static void main( String[] args ) {
049:    		// yの分割数
050:    		int yn;
051:    
052:    		// 1000分割
053:    		yn = 1000;
054:    		System.out.println( "分割数:" + yn+ "     π=" + getPI_1( yn ) );
055:    
056:    		// 10000分割
057:    		yn = 10000;
058:    		System.out.println( "分割数:" + yn+ "    π=" + getPI_1( yn ) );
059:    
060:    		// 100000分割
061:    		yn = 100000;
062:    		System.out.println( "分割数:" + yn+ "   π=" + getPI_1( yn ) );
063:    
064:    		// 1000000分割
065:    		yn = 1000000;
066:    		System.out.println( "分割数:" + yn+ "  π=" + getPI_1( yn ) );
067:    
068:    		// 10000000分割
069:    		yn = 10000000;
070:    		System.out.println( "分割数:" + yn+ " π=" + getPI_1( yn ) );
071:    	}
072:    }

CalcPI1を実行

C:\talavax\javasample>java CalcPI1

CalcPI1.javaの出力結果

分割数:1000     π=3.1415554669110293
分割数:10000    π=3.1415914776112435
分割数:100000   π=3.141592616398606
分割数:1000000  π=3.1415926524339723
分割数:10000000 π=3.1415926531488605

分割数を大きくするとπの計算値が、実際のπの値に近づいています。

実際の円周率πは、

 3.141592653589793238462・・・

です。分割数を1000000にすると小数点以下第9桁まで一致しました。

001:    public class CalcPI1 {

クラス名を、CalcPI1としています。

002:    	// πを計算するメソッド
003:    	public static double getPI_1( int yn )

円周率πを計算するメソッドです。int型変数ynは分割数で、計算する台形の個数を表します。

005:    		double upperbase;	// 台形の上底
006:    		double lowerbase;	// 台形の下底
007:    		double height;		// 台形の高さ
008:    		double lowery;		// 台形の下底の座標
009:    		double area;		// 円の面積
010:    		double aread;		// 台形の面積

計算に使用する変数を宣言しています。

012:    		// 台形の高さ(円の半径をynで割る)
013:    		height = 1.0 / (double)yn;

半径1.0を変数ynで割って台形の高さを計算し、double型変数heightに代入しています。

015:    		// 上底の初期値
016:    		upperbase = 0.0;

最初に計算する台形の上底に0.0を代入しています。このプログラムでは、上から下に向けて台形の面積を計算していきます。

018:    		// 下底のy座標の初期値
019:    		lowery = 1.0 - height;

初期の下底のy座標を変数loweryに代入しています。上底のy座標は1.0なので、下底のy座標は1.0から高さheightを引いた値になります。

021:    		// 計算開始
022:    		area = 0.0;
023:    		for ( int i = 0; i < yn; ++ i ) {

ここから台形の面積を、指定した分割数yn回計算していきます。そして、変数areaに台形の面積を足して行きます。変数areaの初期値は0.0です。

024:    			// 下底の計算
025:    			lowerbase = Math.sqrt( 1.0 - lowery * lowery );

下底のy座標loweryから、下底を計算しています。

下底はy座標loweryを持つ単位円上のプラスのx座標になるので、12=lowery2+lowerbase2を満たすlowerbaseが下底となります。

027:    			// 台形の面積計算
028:    			aread = ( upperbase + lowerbase ) * height / 2.0;

上底と下底と高さで台形の面積を計算して変数areadに代入しています。

030:    			// 円の面積に台形の面積を足す
031:    			area += aread;

変数areaに台形の面積areadを足しています。

033:    			// 下底を上底に代入
034:    			upperbase = lowerbase;

下底を上底に代入しています。計算した台形の下底が、次に計算する台形の上底になるためです。

036:    			// 下底のy座標からheightを引く
037:    			lowery -= height;

下底はy座標loweryから高さheightを引いています。

040:    		// 1/4円の面積を4倍
041:    		area = area * 4.0;

for文を抜けると、変数areaには単位円の四分の一の面積が格納されています。変数areaに4を掛けて単位円全体の面積を求めます。

043:    		// 結果を戻す
044:    		return area;

return文で、単位円の面積areaを戻します。

048:    	public static void main( String[] args ) {
049:    		// yの分割数
050:    		int yn;
051:    
052:    		// 1000分割
053:    		yn = 1000;
054:    		System.out.println( "分割数:" + yn+ "     π=" + getPI_1( yn ) );
055:    
056:    		// 10000分割
057:    		yn = 10000;
058:    		System.out.println( "分割数:" + yn+ "    π=" + getPI_1( yn ) );
059:    
060:    		// 100000分割
061:    		yn = 100000;
062:    		System.out.println( "分割数:" + yn+ "   π=" + getPI_1( yn ) );
063:    
064:    		// 1000000分割
065:    		yn = 1000000;
066:    		System.out.println( "分割数:" + yn+ "  π=" + getPI_1( yn ) );
067:    
068:    		// 10000000分割
069:    		yn = 10000000;
070:    		System.out.println( "分割数:" + yn+ " π=" + getPI_1( yn ) );
071:    	}

分割数を変えて、円周率πを計算した結果を表示しています。

■関連コンテンツ

円周率π(パイ) π(パイ)の意味と、Math.PIの使い方について解説
台形の面積計算 台形の上底と下底と高さを使って面積を計算する方法を解説

■新着情報

2019.09.13 長さの単位変換 1マイル、1フィートは何m?
2019.09.06 クイックソート 高速に配列に並び替える方法
2019.09.05 中央値(メディアン) 配列に格納されている値の中央値を求める
2019.09.05 最頻値 配列から出現回数が最も多い値の取得
2019.09.03 配列値の反転 配列の反転処理
2019.08.05 トランプの操作 トランプを操作するクラス

■広告

法人向けのETC専用カード

~約8,000名の受講生と80社以上の導入実績~ 企業向けプログラミング研修ならCodeCamp

日本最大級ショッピングサイト!お買い物なら楽天市場

 

 

 

 

 

 

 

 

 

Topへ