0

我正在尝试在这个系列中使用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

任何帮助将不胜感激。

4

3 回答 3

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 函数进行除法,将结果视为您的next变量。

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

于 2013-02-02T16:17:48.740 回答
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 浮点数才能使这项工作。

于 2013-02-02T16:20:40.257 回答
0

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

于 2013-02-02T16:24:08.727 回答