2013-02-02 6 views
0

Je suis en train de calculer Pi à l'aide GMP (5.1.0) avec cette série: Pi = 3 + 4/(2 * 3 * 4) - 4/(4 * 5 * 6) + 4/(6 * 7 * 8) - ...Calcul de Pi en utilisant GMP

Qu'est-ce que je l'ai fait est:

#include <stdio.h> 
#include <gmp.h> 

mpz_t pi; 
mpz_t next; // Every number in the serie that comes after 3 

int a = 2, b = 3, c = 4; // Divisors. Everytime add 2 to all of them at the end of the loop 
int i; // Loop counter 

int main (void) { 
    mpz_init (pi); mpz_init (next); 
    mpz_set_str (pi, "3", 10); 

    for (i = 2 ;; ++i) { 
     printf ("%s\n", mpz_get_str (NULL, 10, pi)); 

     mpz_set_d (next, 4/(a * b * c)); 

     if (i % 2 == 0) 
      mpz_add (pi, pi, next); 
     else 
      mpz_sub (pi, pi, next); 

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

    mpz_clear (next); 
    mpz_clear (pi); 
} 

Je suis compilation sur Linux 64 bits:

gcc -Wall -pedantic -o foo foo.c -lgmp 

Sortie:

3 
3 
3 
and so on 

Résultats escomptés:

3 
3.1666... 
3.1333... 
3.1452... 
3.1396... 
and so on 

Toute aide sera grandement appréciée.

+0

Quel débogage avez-vous fait jusqu'à présent? –

+0

Vous effectuez tous ces calculs à l'aide de grands entiers et imprimez une valeur entière. D'où viennent les valeurs décimales? – talonmies

Répondre

1

Vous faites la division entière:

mpz_set_d (next, 4/(a * b * c)); 
//    ^ ^^^^^^^^^^^ 
//    int  int 

deux entiers divisant leur arrondir vers zéro, ce qui est 0 dans ce cas, puisque a * b * c > 4 à chaque itération.

Vous pouvez résoudre ce problème en écrivant

mpz_set_d (next, 4.0/(a * b * c)); 
//    ^^^ ^^^^^^^^^^^ 
//    double  int 

Cependant, vous devez effectuer la division en utilisant GMP depuis le code ci-dessus souffre des limites des types de numéros natifs. En outre, le résultat de cette division ne doit pas être stocké dans un entier GMP, mais dans un flotteur GMP:

mpf_t next; 
//... 
mpf_set_d(next, 4.0); 
mpf_div(next, a); 
mpf_div(next, b); 
mpf_div(next, c); 

Notez que aussi a, b, c doivent être flotte GMP afin de faire ce travail.

1

Votre problème est très probablement sur cette ligne:

mpz_set_d (next, 4/(a * b * c)); 

Sur cette ligne vous passez essentiellement 0 à la fonction mpz_set_d, que je suppose ensembles votre numéro. C'est parce que vous évaluez 4/(a * b * c) en utilisant l'arithmétique des nombres entiers. (a * b * c) est toujours supérieur à 4, donc cette expression est toujours évaluée à 0. Ceci est et non ce que vous voulez.

Vous devriez probablement mettre 4 et (a * b * c) en deux nombres distincts à virgule flottante GMP et utiliser les fonctions de GMP pour faire la divison, le traitement le résultat que votre variable next.

EDIT: En regardant la documentation GMP, la famille de fonctions mpz traite des nombres entiers. Vous avez probablement besoin d'utiliser les fonctions mpf, qui traitent des flottants, ou les fonctions mpq, qui traitent des fonctions rationnelles.

0

4/(a * b * c) est toujours zéro.

+2

vrai, mais semble drôle comme une déclaration autonome ;-) Je vous recommande d'ajouter "parce que a, b et c sont des entiers". – stefan