使用GMP计算Pi

时间:2013-02-02 16:13:39

标签: c gmp pi

我正在尝试使用此系列使用GMP(5.1.0)计算Pi: Pi = 3 + 4 / (2 * 3 * 4) - 4 / (4 * 5 * 6) + 4 / (6 * 7 * 8) - ...

我所做的是:

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

我在64位Linux上编译:

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

输出:

3
3
3
and so on

预期输出:

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

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

你的问题最有可能出现在这条线上:

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

在这一行,你基本上将0传递给mpz_set_d函数,我假设你设置了你的数字。

那是因为您正在使用整数运算来评估4 / (a * b * c)(a * b * c)始终大于4,因此此表达式的计算结果始终为0.这是您想要的内容。

您应该将4(a * b * c)放入两个单独的GMP浮点数中,并使用GMP函数来执行divison,将结果视为next变量。

编辑:查看GMP文档,mpz系列函数处理整数。您可能需要使用处理浮点数的mpf函数或处理有理数的mpq函数。

答案 1 :(得分:1)

你做整数除法:

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

除以两个整数会将它们舍入为零,在这种情况下为0,因为在每次迭代中都是a * b * c > 4

可以通过编写

来解决这个问题
mpz_set_d (next, 4.0 / (a * b * c));
//               ^^^   ^^^^^^^^^^^
//             double      int

但是,您应该使用GMP执行除法,因为上面的代码受到本机数字类型的限制。此外,此除法的结果不应存储在GMP整数中,而应存储在GMP浮点数中:

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

请注意,a,b,c也必须是GMP浮点数才能使其发挥作用。

答案 2 :(得分:0)

4 / (a * b * c)始终为零。