Comment calculer PI dans C#?

Comment puis-je calculer la valeur de PI en utilisant C#?

je pensais qu'il serait par le biais d'une fonction récursive, si oui, à quoi ressemblerait-il et quels sont les équations mathématiques pour les sauvegarder?

Je ne suis pas trop pointilleux sur la performance, surtout sur la façon de s'y prendre du point de vue de l'apprentissage.

23
c# pi
demandé sur George Stocker 2008-09-02 16:39:12

21 réponses

Si vous voulez la récursivité:

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

ceci deviendrait, après quelques réécritures:

PI = 2 * F(1);

avec F (i):

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

Isaac Newton (vous avez peut-être déjà entendu parler de lui ;) ) a inventé cette astuce. Notez que j'ai oublié la condition finale, pour que ce soit simple. Dans la vraie vie, vous sorte de besoin.

40
répondu wvdschel 2014-03-07 15:31:37

Que Diriez-vous d'utiliser:

double pi = Math.PI;

si vous voulez plus de précision que cela, vous aurez besoin d'utiliser un système algorithmique et le type décimal.

20
répondu Skizz 2012-07-03 13:13:16

il y a quelques trucs vraiment, vraiment vieux que je suis surpris de ne pas voir ici.

atan(1) == PI / 4, donc un vieux châtaignier quand une fonction arc-tangent digne de confiance est actuelle est de 4*atan(1).

très mignon, ratio fixe estimation que fait le vieux Western 22/7 ressembler à de la saleté est 355/113, ce qui est bon pour plusieurs décimales (au moins trois ou quatre, je pense). Dans certains cas, cela est même assez bon pour arithmétique entière: multiplier par 355 puis diviser par 113.

355/113 est aussi facile de s'engager dans la mémoire( pour certaines personnes de toute façon): comptez un, un, trois, trois, cinq, cinq et souvenez-vous que vous nommez les chiffres dans le dénominateur et le numérateur (si vous oubliez quel triplet va en haut, la pensée d'une microseconde va généralement le redresser).

notez que 22/7 vous donne: 3.14285714, ce qui est faux aux millièmes.

355/113 vous donne 3.14159292 ce qui n'est pas mal jusqu'à ce que le dix-millièmes.

Acc. /usr/include/math.h sur ma boîte, M_PI est #define avait en: 3,14159265358979323846 ce qui est probablement bon pour autant.

la leçon que vous tirez de L'estimation de PI est qu'il y a beaucoup de façons de le faire, aucun ne sera jamais parfait, et vous devez les trier par l'utilisation prévue.

355/113 est une vieille estimation chinoise, et je crois qu'elle date d'avant 22/7 de nombreuses années. Elle m'a été enseignée par un professeur de physique quand j'étais le premier cycle.

6
répondu 2008-09-02 21:01:34

Si vous regardez de plus près dans ce très bon guide:

Modèles de Programmation Parallèle: la Compréhension et l'Application de Modèles Parallèles avec la .NET Framework 4

vous trouverez à la Page 70 cette implémentation mignonne (avec des changements mineurs de mon côté):

static decimal ParallelPartitionerPi(int steps)
{
    decimal sum = 0.0;
    decimal step = 1.0 / (decimal)steps;
    object obj = new object();

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

            return partial;
        },
        partial => { lock (obj) sum += partial; });

    return step * sum;
}
6
répondu Oliver 2013-12-09 07:40:51

Bon aperçu des différents algorithmes:

Je ne suis pas sûr de la complexité revendiquée pour l'algorithme Gauss-Legendre-Salamin dans le premier lien (je dirais O(N log^2(N) log(log(N))).

je ne vous encourage à l'essayer, cependant, la convergence est vraiment rapide.

aussi, je ne suis pas vraiment sûr de pourquoi essayer de convertir un algorithme procédural assez simple en un algorithme récursif?

notez que si vous êtes intéressé par la performance, alors travailler avec une précision limitée (typiquement, nécessitant un "double", "float",... output) n'a pas vraiment de sens, car la réponse évidente dans un tel cas est simplement de hardcode la valeur.

4
répondu OysterD 2008-09-02 19:57:55

Voici un article sur le Calcul de PI en C#:

http://www.boyet.com/Articles/PiCalculator.html

3
répondu Espo 2008-09-02 12:51:43

Qu'est-ce que PI? La circonférence d'un cercle divisé par son diamètre.

en infographie vous pouvez tracer/dessiner un cercle avec son centre à 0,0 d'un point initial x, y, le prochain point x', y' peut être trouvé en utilisant une formule simple: x' = x + y / h: y' = y-x' / H

h est habituellement une puissance de 2 de sorte que la division peut être faite facilement avec un décalage (ou en soustrayant de l'exposant sur un double). h veut aussi être le rayon r du cercle. Un point de départ facile serait be x = r, y = 0, puis compter c le nombre de pas jusqu'à x <= 0 pour tracer un quart de cercle. PI est de 4 * c / r ou PI à 4 * c / h

la récursion à une grande profondeur, est habituellement peu pratique pour un programme commercial, mais la récursion de queue permet à un algorithme d'être exprimé de façon récursive, tout en étant mis en œuvre en boucle. Les algorithmes de recherche récursifs peuvent parfois être mis en œuvre en utilisant une file d'attente plutôt que la pile du processus, la recherche doit revenir d'un point mort et prendre un autre chemin - ces points de backtrack peuvent être placés dans une file d'attente, et plusieurs processus peuvent supprimer la file d'attente des points et essayer d'autres chemins.

2
répondu 2008-09-02 20:36:39

Calculer comme ceci:

x = 1 - 1/3 + 1/5 - 1/7 + 1/9  (... etc as far as possible.)
PI = x * 4

Vous avez Pi !!!

C'est la méthode la plus simple que je connaisse.

la valeur de PI converge lentement vers la valeur réelle de Pi (3.141592165......). Si vous itérez plus de fois, le mieux.

1
répondu Niyaz 2008-09-02 12:58:23

Voici une bonne approche (de la principale entrée de Wikipedia sur les pi); elle converge beaucoup plus rapidement que la formule simple discutée ci-dessus, et est tout à fait acceptable à une solution récursive si votre intention est de poursuivre la récursion comme un exercice d'apprentissage. (En supposant que vous êtes après l'expérience d'apprentissage, Je ne donne pas de code réel.)

La formule sous-jacente est la même que ci-dessus, mais cette approche de la moyenne des sommes partielles d'accélérer le convergence.

définir une fonction à deux paramètres, pie( h, w), telle que:

pie(0,1) = 4/1
pie(0,2) = 4/1 - 4/3
pie(0,3) = 4/1 - 4/3 + 4/5
pie(0,4) = 4/1 - 4/3 + 4/5 - 4/7
... and so on

donc votre première occasion d'explorer la récursion est de coder ce calcul " horizontal "comme le paramètre" Largeur "augmente (pour" hauteur " de zéro).

puis Ajouter la deuxième dimension avec cette formule:

pie(h, w) = (pie(h-1,w) + pie(h-1,w+1)) / 2

qui est utilisé, bien sûr, seulement pour des valeurs de h supérieures à zéro.

ce qui est bien avec cet algorithme, c'est qu'on peut facilement se moquer il up avec un tableur pour vérifier votre code que vous explorez les résultats produits par des paramètres de plus en plus grands. Au moment de calculer pie(10,10), vous aurez une valeur approximative pour pi qui est assez bonne pour la plupart des fins d'ingénierie.

1
répondu joel.neely 2008-09-02 13:57:49
Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next)/(2*next + 1)*4)
1
répondu Dean Chalk 2012-07-03 13:13:28
using System;

namespace Strings
{
    class Program
    {
        static void Main(string[] args)
        {

/*          decimal pie = 1; 
            decimal e = -1;
*/
            var stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start(); //added this nice stopwatch start routine 

  //leibniz formula in C# - code written completely by Todd Mandell 2014
/*
            for (decimal f = (e += 2); f < 1000001; f++)
            {
                 e += 2;
                 pie -= 1 / e;
                 e += 2;
                 pie += 1 / e;
                 Console.WriteLine(pie * 4);
            }

                 decimal finalDisplayString = (pie * 4);
                 Console.WriteLine("pie = {0}", finalDisplayString);
                 Console.WriteLine("Accuracy resulting from approximately {0} steps", 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

            decimal pie = 0;
            decimal a = 2;
            decimal b = 3;
            decimal c = 4;
            decimal e = 1;

            for (decimal f = (e += 1); f < 100000; f++) 
            // Increase f where "f < 100000" to increase number of steps
            {

                pie += 4 / (a * b * c);

                a += 2;
                b += 2;
                c += 2;

                pie -= 4 / (a * b * c);

                a += 2;
                b += 2;
                c += 2;

                e += 1;
            }

            decimal finalDisplayString = (pie + 3);
            Console.WriteLine("pie = {0}", finalDisplayString);
            Console.WriteLine("Accuracy resulting from {0} steps", e); 

            stopwatch.Stop();
            TimeSpan ts = stopwatch.Elapsed;
            Console.WriteLine("Calc Time {0}", ts); 

            Console.ReadLine();

         }
     }
 }
1
répondu ronalt MkDonalt 2014-09-03 07:14:31
    public static string PiNumberFinder(int digitNumber)
    {
        string piNumber = "3,";
        int dividedBy = 11080585;
        int divisor = 78256779;
        int result;

        for (int i = 0; i < digitNumber; i++)
        {
            if (dividedBy < divisor)
                dividedBy *= 10;

            result = dividedBy / divisor;

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

            dividedBy = dividedBy - divisor * result;
        }

        return piNumber;
    }
1
répondu Curious 2014-11-02 08:57:05

dans n'importe quel scénario de production, je vous forcerais à chercher la valeur, au nombre voulu de points décimaux, et à la stocker comme un "const" quelque part où vos classes peuvent l'obtenir.

(sauf si vous écrivez un logiciel spécifique 'Pi' scientifique...)

0
répondu Anthony Mastrean 2008-09-02 13:03:14

en ce qui Concerne...

... comment s'y prendre du point de vue de l'apprentissage.

essayez-vous d'apprendre à programmer des méthodes scientifiques? ou pour produire un logiciel de production? J'espère que la communauté considère cela comme une question valable, et pas pinailler.

dans les deux cas, je pense que l'écriture de votre propre Pi est un problème résolu. Dmitry a montré le calcul.PI ' constant déjà. Attaquer un autre problème dans le même espace! Allez pour le Newton Générique des approximations ou de quelque chose de lisse.

0
répondu Anthony Mastrean 2008-09-02 13:53:47

@Thomas Kammeyer:

notez Qu'Atan (1.0) est très souvent codé en dur, donc 4*Atan(1.0) n'est pas vraiment un "algorithme" si vous appelez une fonction atan de bibliothèque (un bon nombre ont déjà suggéré de procéder en remplaçant Atan(x) par une série (ou un produit infini) pour lui, puis en l'évaluant à x=1.

Également il y a très peu de cas où vous auriez besoin de pi avec plus de précision que quelques dizaines de bits (qui peut être facilement codé en dur!). J'ai travaillé sur applications en mathématiques où, pour calculer certains (assez compliqué) objets mathématiques (qui étaient polynomial avec des coefficients entiers), j'ai dû faire l'arithmétique sur les nombres réels et complexes (y compris le calcul pi) avec une précision allant jusqu'à quelques millions de bits... mais ce n'est pas très fréquents "dans la vraie vie":)

Vous pouvez consulter l'exemple suivant code.

0
répondu OysterD 2008-09-02 21:13:53

le lien suivant montre comment calculer la constante pi basée sur sa définition comme intégrale, qui peut être écrite comme limite d'une sommation, c'est très intéressant: https://sites.google.com/site/rcorcs/posts/calculatingthepiconstant Le fichier "Pi en tant que partie intégrante" explique cette méthode utilisée dans ce post.

0
répondu Rodrigo 2012-11-17 10:59:06

tout d'abord, notez que C# peut utiliser les maths.Champ PI du framework .NET:

https://msdn.microsoft.com/en-us/library/system.math.pi(v=vs. 110).aspx

la caractéristique agréable ici est que c'est un double de pleine précision que vous pouvez soit utiliser, ou comparer avec les résultats calculés. Les onglets de cette URL ont des constantes similaires pour C++, F# et Visual Basic.

Pour calculer plus d'endroits, vous pouvez écrire votre propre étendue précision de code. Celui qui il est rapide à code et raisonnablement rapide et facile à programmer est:

Pi = 4 * [4 * arctan (1/5) - arctan (1/239)]

cette formule et beaucoup d'autres, y compris certains qui convergent à des taux étonnamment rapides, tels que 50 chiffres Par terme, sont à Wolfram:

Formules Wolfram Pi

0
répondu Larry Paden 2016-11-18 21:25:39

PI (π) peut être calculé en utilisant séries infinies. En voici deux exemples:

Gregory-Leibniz Series: