25


17

C#を使用してPIの値を計算する方法

私はそれが再帰関数を介して行われると考えていました、もしそうなら、それはどのように見えるでしょうかそしてそれをバックアップするための数学の方程式はありますか?

私はパフォーマンスに関してあまりにもうるさいことではありません。主に学習の観点からそれをどうやって進めるかということです。

21 Answer


41


再帰が必要な場合:

PI = 2 *(1 1/3 *(1 2/5 *(1 3/7 *(...))))

これは、いくつか書き直すと次のようになります。

PI = 2 * F(1)。

F(i)の場合:

double F(int i){return 1 i /(2.0 * i 1)* F(i 1); }

アイザックニュートン(あなたは彼の前に聞いたことがあるかもしれません;))がこのトリックを思い付きました。 簡単にするために、終了条件は省略しています。 実生活では、あなたは一種のものを必要としています。


22


どうやって使うの?

double pi = Math.PI;

それ以上の精度が必要な場合は、アルゴリズムシステムとDecimal型を使用する必要があります。


7


この本当に良いガイドを詳しく見てみましょう。

あなたはこのかわいい実装を見つけることができます(私の側からのマイナーチェンジ)。

静的10進数ParallelPartitionerPi(int steps){10進数の合計= 0.0。 10進数ステップ= 1.0 /(10進数)ステップ。オブジェクトobj = new object();

Parallel.ForEach(Partitioner.Create(0、steps)、()=> 0.0、(range、state、partial)=> {(int i = range.Item1; i <range.Item2; i){decimal x = (i  -  0.5)* step; partial = 4.0 /(1.0 x * x);}

部分的に返します。 }、partial => {lock(obj)sum = partial; ;));

戻りステップ* sum }


6


ここで見られないことに私は驚いて、本当に、本当に古いトリックがいくつかあります。

atan(1)== PI / 4なので、信頼できる逆正接関数が存在するときの古いクリは4 * atan(1)です。

古いWestern 22/7を汚れのように見せる非常に可愛い、固定比率の見積もりは355/113で、これは小数点以下の桁数に適しています(少なくとも3つまたは4つ、私は思う)。 場合によっては、これは整数演算には十分です。355を乗算して113で除算します。

1、1、3、3、5、5を数えて、分母と分子の数字に名前を付けていることを忘れないでください(どのトリプレットを使用するか忘れた場合)。上に、マイクロ秒の考えは通常それをまっすぐにしようとしている)です。

22/7があなたに与えることに注意してください:3.14285714、これは1000分の1で間違っています。

355/113はあなたに3.14159292を与えます、それは1000万分の1まで間違っていません。

Acc。 私の箱の/usr/include/math.hでは、M_PIは#define’d:3.14159265358979323846となっています。

PIを見積もることから得られる教訓は、それを実行する方法はたくさんあるということです。どれも完璧ではないでしょう、そしてあなたは意図した用途によってそれらを分類しなければなりません。

355/113は中国の古い見積もりであり、私はそれが長年で22/7より前になると信じています。 私が学部生の頃、物理学の教授から教えられました。


4


さまざまなアルゴリズムの概要

最初のリンクでGauss-Legendre-Salaminアルゴリズムが要求する複雑さについてはよくわかりません(O(N log ^ 2(N)log(log(N)))と言います)。

試してみることをお勧めしますが、コンバージェンスは本当に速いです。

また、なぜ非常に単純な手続き型アルゴリズムを再帰的なものに変換しようとしているのか、私にはよくわかりません。

パフォーマンスに興味があるなら、限界のある精度で作業してください(通常、 'double'、 'float’などが必要です)。 そのような場合の明白な答えは単に値をハードコードすることであるため、output)は実際には意味がありません。


3


これはC#でPIを計算することに関する記事です:


2


PIとは 円の円周を直径で割ったもの。

コンピュータグラフィックスでは、初期点x、yからその中心を0,0とする円をプロット/描くことができ、次の点x '、y’は簡単な式を使って見つけることができます。x '= xy / h:y' = y - x '/ h

hは通常、2の累乗であるため、除算はシフトで簡単に実行できます(または倍精度の指数から減算します)。 hはまたあなたの円の半径rになりたいです。 簡単な開始点はx = r、y = 0、そしてx ⇐ 0になるまでcを歩数で数えて四分の一円を描くことです。 PIが4 * c / rまたはPIが4 * c / h

任意の大きな深さへの再帰は、通常、商用プログラムには実用的ではありませんが、末尾再帰は、ループとして実装されている間、アルゴリズムを再帰的に表現することを可能にします。 再帰的な検索アルゴリズムは、プロセスのスタックではなくキューを使って実装されることがあります。検索は行き詰まりから後戻りして別の道をたどらなければなりません。 - これらのバックトラックポイントはキューに入れることができ、複数のプロセスがポイントのキューを解除して他のパスを試すことができます。


1


Enumerable.Range(0、100000000)。集計(0d、(tot、next)=> tot = Math.Pow(-1d、next)/(2 * next 1)* 4)


1


public static string PiNumberFinder(int digitNumber){string piNumber = "3、"; int splitBy = 11080585。 int除数= 78256779。 intの結果

for(int i = 0; i <digitNumber; i){if(splitBy <divisor)divideBy * = 10;

結果= splitBy / divisor;

string resultString = result.ToString(); piNumber = resultString;

splitBy = divideBy  -  divisor * result; }

piNumberを返します。 }


1


システムを使用する。

名前空間文字列{クラスプログラム{static void Main(string [] args){

/ *小数パイ= 1。 10進数e = -1。 * / var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); //この素敵なストップウォッチスタートルーチンを追加しました

// C#のleibniz式 -  Todd Mandell 2014 / *によって完全に記述されたコード。(10進数f =(e = 2); f <1000001; f){e = 2;パイ -  = 1 / e; e = 2。パイ= 1 / e。 Console.WriteLine(円* 4); }

decimal finalDisplayString =(円* 4); Console.WriteLine( "pie = {0}"、finalDisplayString); Console.WriteLine( "約{0}ステップの精度"、e / 4); * /

// Nilakantha formula - code written completely by Todd Mandell 2014
// π = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) - (4/(12*13*14) etc

小数パイ= 0。 10進数a = 2。 10進数b = 3。 10進数c = 4。 10進数e = 1。

for(decimal f =(e = 1); f <100000; f)//ステップ数を増やすには、fを増やします。ここで "f <100000"です。

パイ= 4 /(a * b * c);

a = 2。 b = 2。 c = 2。

パイ -  = 4 /(a * b * c);

a = 2。 b = 2。 c = 2。

e = 1。 }

decimal finalDisplayString =(パイ3); Console.WriteLine( "pie = {0}"、finalDisplayString); Console.WriteLine( "{0}ステップの精度"、e);

stopwatch.Stop(); TimeSpan ts = stopwatch.Elapsed; Console.WriteLine( "計算時間{0}"、ts);

Console.ReadLine();

}}}