web-dev-qa-db-ja.com

pi(π)はどのように計算されますか?

与えられた小数点以下の桁数にpi(π)を返す関数をどのように書くことができますか?

速度は問題ではありません。私は http://bellard.org/pi/ を見てきましたが、それでもpiのn桁目を取得する方法がわかりません。

34
jmasterx

微積分には、テイラー級数と呼ばれるものがあり、多くの無理値を任意の精度で計算する簡単な方法を提供します。

Pi/4 = 1-1/3 + 1/5-1/7 + ...
(from http://www.math.hmc.edu/funfacts/ffiles/30001.1-3.shtml

精度の桁数が安定するまで、これらの用語を追加していきます。

テイラーの定理は強力なツールですが、定理を使用したこのシリーズの派生は問題の範囲を超えています。これは、初年度の標準的な微積分であり、詳細に興味がある場合は簡単にグーグルできます。


これが円周率を計算する最も実用的な方法であることを示唆するつもりはありませんでした。それはあなたが本当にそれをする必要がある理由に依存するでしょう。実用的な目的のために、公開されている多くのバージョンの1つから必要な桁数だけコピーする必要があります。私はこれを、不合理な値を無限の系列と同等と見なす方法の簡単な紹介として提案していました。

31
Alan

πの数値近似 には多くのアルゴリズムがあります。

27
James McNellis
12
el.pescado

JeffHのすべてのバリエーションを保存する方法の代わりに、最大桁数を保存し、不要なものを切り捨てることができます。

#include <string>
#include <iostream>
using std::cout; using std::endl; using std::string;

// The first 99 decimal digits taken from:
// http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
// Add more as needed.
const string pi =
  "1415926535"
  "8979323846"
  "2643383279"
  "5028841971"
  "6939937510"
  "5820974944"
  "5923078164"
  "0628620899"
  "8628034825"
  "342117067";

// A function in C++ that returns pi to X places
string CalcPi(const size_t decimalDigitsCount) 
{
  string returnValue = "3";
  if (decimalDigitsCount > 0)
  {
    returnValue += "." + pi.substr(0, decimalDigitsCount);
  }
  return returnValue;
} 

int main()
{
  // Loop through all the values of "pi at x digits" that we have. 
  for (size_t i = 0; i <= pi.size(); ++i) 
  {
    cout << "pi(" << i << "): " << CalcPi(i) << endl;
  } 
}

http://codepad.org/6mqDa1zj

8
Bill

お探しのアルゴリズムは、「スピゴットアルゴリズム」と呼ばれるものです。 1つの特定の種類は、 [〜#〜] bbp [〜#〜] (Bailey-Borwein-Plouffe)式です。

私はそれがあなたが探しているものだと信じています。

6
Mike Bailey

" O(n ^ 2)の任意の底のpiのn桁目の計算 "を試してください。これはおそらく、任意の(readhuge)精度の浮動小数点数を必要とせず、ベース10(または任意のその他)。

6
slacker

" πIN THE MANDELBROT SET "は、複素平面上の一連の点の間の奇妙な関係と、それらの「マンデルブロ数」の計算方法(より適切な用語がないため...に必要な反復数)を調査します。シーケンス内のポイントがマンデルブロ集合のメンバーではないことを確認します)PIに関連します。

実用的ですか?おそらく違います。

意外で面白い?私はそう思う。

5
andand

あなたはそれらを計算する代わりに値を調べてもいいですか?

関数がcalculate値でなければならないことを明示的に指定しなかったため、考えられる解決策は次のとおりです計算できる桁数に上限がある場合

// Initialize pis as far out as you want. 
// There are lots of places you can look up pi out to a specific # of digits.
double pis[] = {3.0, 3.1, 3.14, 3.141, 3.1416}; 

/* 
 * A function that returns pi out to a number of digits (up to a point)
 */
double CalcPi(int x)
{
    // NOTE: Should add range checking here. For now, do not access past end of pis[]
    return pis[x]; 
}

int main()
{
    // Loop through all the values of "pi at x digits" that we have.
    for (int ii=0; ii<(int)sizeof(pis)/sizeof(double); ii++)
    {
        double piAtXdigits = CalcPi(ii);
    }
}

この方法でCalcPi()を記述する(ニーズを満たす場合)には、上限内のXの値に対して同じように速く叫ぶという副次的な利点があります。

3
JeffH

公式から始めます

pi = 16 arctan (1/5) - 4 arctan (1/239)

Googleは通常の人間が理解できるこの式の証明と逆正接関数を計算する式を簡単に見つけます。これにより、piの数千桁を非常に簡単かつ迅速に計算できます。

3
gnasher729

追加した(または減算した)最後の項に基づいて精度を確認できます。アランのシーケンスの各項の振幅は常に減少しており、各項の符号は交互に変化するため、合計は最後の項より大きく変化しません。

そのバブルの翻訳:1/5を追加した後、合計は1/5を超えて変化しないため、正確には1/5以内です。もちろん、これに4を掛ける必要があるので、実際には4/5までしか正確ではありません。

残念ながら、数学は常に10進数に簡単に変換できるとは限りません。

2
Mashmagar

私の2セント...これは最速ではないかもしれませんが、理解するのは非常に簡単だと思います。私は数学の講義中に自分でそれを思いつきました、そしてそれを文学の他のどこかで実際に見たことはありません。私は天才であるか、本当に愚かであるか、または数学に関する本を読むことに本当に注意を払わないか、または上記のすべて... :)

とにかく...単位円から始めましょう。 x ^ 2 + y ^ 2 = 1であることがわかっているため、y = sqrt(1-x ^ 2)です。また、単位円の面積がPIであることも知っています。ここで、0から1の範囲の関数sqrt(1-x ^ 2)の積分を取ると、PIの4分の1が得られます。したがって、4を掛けてPIを取得します。

PI formula

これを分析的に解決しようとすれば、PIを取り戻すことができると確信しています。しかし、それを数値的に解くプログラムを書くのはとても簡単です。次のものはCにあります。

#include <math.h>
#include <stdio.h>

void main(void) {
    double interval=0.0000001,area=0,x,y;

    for (x=0; x<1; x+=interval)
        area+=4*interval*sqrt(1-x*x);

    printf("pi ~ %.20f\n",area);
}

上記のintervalの設定で実行すると、次のようになります。

pi ~ 3.14159285415672595576

したがって、10,000,000回の反復で6つの正しい小数が得られます。最も効率的ではありませんが、それは私の赤ちゃんです... :)

1
pi = function () {
    let pi = 3;
    let a = 3;
    let even = false;
    let turn;

    while (a <= 90000) {
        turn = (4/((Math.pow(a, 3)) - (a)));

        if(even){
            turn = turn*-1;
            even = false;
        } else {
            even = true;
        }
        pi = pi + turn;
        a = a + 2;
    }
    return pi;
};
0
T.Arnold