我正在尝试使用此系列使用GMP(5.1.0)计算Pi:
我所做的是:
#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
非常感谢任何帮助。
答案 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)
始终为零。