web-dev-qa-db-fra.com

Comment est calculé pi (π)?

Comment puis-je écrire une fonction qui retournera pi (π) à un nombre donné de décimales?

La vitesse n'est pas une préoccupation. J'ai regardé http://bellard.org/pi/ , mais je ne comprends toujours pas comment obtenir le nième chiffre de pi.

34
jmasterx

Dans le calcul, il y a une chose appelée Taylor Series qui fournit un moyen facile de calculer de nombreuses valeurs irrationnelles avec une précision arbitraire.

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

Continuez à ajouter ces termes jusqu'à ce que le nombre de chiffres de précision que vous souhaitez stabiliser.

Le théorème de Taylor est un outil puissant, mais la dérivation de cette série en utilisant le théorème dépasse la portée de la question. C'est le calcul universitaire standard de première année et est facilement googlable si vous êtes intéressé par plus de détails.


Je ne voulais pas laisser entendre que c'est la méthode la plus pratique pour calculer pi. Cela dépendrait de la raison pour laquelle vous devez vraiment le faire. Pour des raisons pratiques, vous devez simplement copier autant de chiffres que vous le souhaitez à partir d'une des nombreuses versions publiées. Je proposais cela comme une simple introduction de la façon dont les valeurs irrationnelles peuvent être assimilées à des séries infinies.

31
Alan

Il existe de nombreux algorithmes pour approximation numérique de π .

27
James McNellis
12
el.pescado

Comme alternative à la méthode de JeffH pour stocker chaque variation, vous pouvez simplement stocker le nombre maximum de chiffres et couper ce dont vous n'avez pas besoin:

#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

Je crois que l'algorithme que vous recherchez est ce que l'on appelle un "algorithme de broche". Un type particulier est la formule BBP (Bailey-Borwein-Plouffe).

Je crois que c'est ce que vous recherchez.

6
Mike Bailey

Essayez " Calcul du nième chiffre de pi dans n'importe quelle base dans O (n ^ 2) ". C'est probablement l'algorithme le plus rapide connu qui ne nécessite pas de flotteurs de précision arbitraires (lire énormes ), et peut vous donner le résultat directement en base 10 (ou tout autre autre).

6
slacker

" π DANS LE MANDELBROT SET " explore la curieuse relation entre une séquence de points sur le plan complexe et comment calculer leur "nombre de Mandelbrot" (faute d'un meilleur terme ... le nombre d'itérations nécessaires pour déterminer que les points de la séquence ne sont pas membres de l'ensemble de Mandelbrot) se rapporte à PI.

Pratique? Probablement pas.

Inattendu et intéressant? Je le pense.

5
andand

Êtes-vous prêt à rechercher des valeurs au lieu de les calculer?

Puisque vous n'avez pas spécifié explicitement que votre fonction doit calculer valeurs, voici une solution possible si vous êtes prêt à avoir une limite supérieure sur le nombre de chiffres qu'elle peut "calculer":

// 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);
    }
}

L'écriture de CalcPi () de cette façon (si elle répond à vos besoins) a l'avantage secondaire d'être aussi rapide à crier pour toute valeur de X dans votre limite supérieure.

3
JeffH

Je commencerais par la formule

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

Google trouvera facilement une preuve de cette formule que les êtres humains normaux peuvent comprendre, et une formule pour calculer la fonction tangente de l'arc. Cela vous permettra de calculer facilement et rapidement quelques milliers de chiffres décimaux de pi.

3
gnasher729

Vous pouvez déterminer la précision en fonction du dernier terme que vous avez ajouté (ou soustrait). Étant donné que l'amplitude de chaque terme dans la séquence d'Alan diminue toujours et que chaque terme alterne en signe, la somme ne changera pas plus que le dernier terme.

Traduire ce babillage: après avoir ajouté 1/5, la somme ne changera pas plus de 1/5, vous êtes donc précis à 1/5 près. Bien sûr, vous devrez multiplier cela par 4, vous n'êtes donc vraiment précis qu'à 4/5.

Malheureusement, les mathématiques ne se traduisent pas toujours facilement en chiffres décimaux.

2
Mashmagar

Mes deux cents ... Ce n'est peut-être pas le plus rapide, mais je pense que c'est assez facile à comprendre. Je l'ai inventé moi-même lors d'un cours de mathématiques, et je ne l'ai vraiment vu nulle part ailleurs dans la littérature. Soit je suis un génie, vraiment stupide, soit je ne fais pas vraiment attention à lire des livres sur les mathématiques, ou tout ce qui précède ... :)

Quoi qu'il en soit ... Commencez par le cercle unitaire. Nous savons que x ^ 2 + y ^ 2 = 1, donc y = sqrt (1-x ^ 2). Nous savons également que l'aire du cercle unitaire est PI. Si nous prenons maintenant l'intégrale de la fonction sqrt (1-x ^ 2) dans l'intervalle 0 à 1, nous obtiendrons un quart de PI. Donc, multipliez-le par 4 pour obtenir PI:

PI formula

Si nous essayions de résoudre ce problème analytiquement, je suis sûr que nous récupérerions simplement PI. Mais il est assez facile d'écrire un programme pour le résoudre numériquement. Le suivant est en 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);
}

En l'exécutant avec le paramètre ci-dessus pour interval, nous obtenons:

pi ~ 3.14159285415672595576

Donc 10 000 000 d'itérations donnent 6 décimales correctes. Pas le plus efficace, mais c'est mon bébé ... :)

1
Mikael Lindqvist
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