3

我需要显示整数平均计算结果的前 100 个含义数字。整数系列存储在 mpz_t 类型的数组中,然后将其与 mpq_t 相加并除以另一个 mpq_t (count)

代码:

mpq_t sum;
mpq_init(sum);
//same for variable count, they are filled from mpz_t

//display for check
gmp_printf("%.Qd\n", sum); <- here everything correct
gmp_printf("%.Qd\n", count); <- here also

mpq_div(sum, sum, count);

//to display with floating point
mpf_t avg;
mpf_init(avg);
mpf_set_q(avg, sum);

gmp_printf("%.100Ff\n", avg);    

最后一行的显示,假设 sum = 2,count = 3 是错误的。它在大约 10-15 位数字之后的上限,并用 0 填充。对于(2/3),它是 0.66666666670000...

所以有两件事:

  1. 我不想把它放在地板/天花板上,只是在 100 位数字后截断
  2. 用有意义的数字填充所有 100 位数字

因此,对于(2/3)所需的输出是:

0.666...666(一百个6,最后也是6)

4

1 回答 1

4

使用 mpf_init2(avg, prec),其中 prec 是所需的最小精度(以位为单位)。请注意,在幕后,GMP 在(通常)32 位或 64 位组中工作,因此计算的实际精度至少是您要求的精度。

防止对输出进行四舍五入将更加困难。我建议使用 MPFR 库。它是一个更完整的浮点库,旨在取代 GMP 的 mpf 类型。

评论太长了。。。。。。

计算超过 100 位只需将 mpf_int(x) 更改为 mpf_init2(x, 333)。333 位应至少获得 100 位十进制数字的精度,但您可能需要稍微增加它。

由于 gmp_printf() 可能会将最后一位数字向上取整,因此获得截断的输出会比较棘手。一种“几乎总是”有效的方法是使用 mpf_get_str() 创建一个精度超过 100 位的字符串,然后截断该字符串。

“几乎总是”是因为一长串 9,比如 ...599999999 将四舍五入到 ...600000000 并且截断的字符串可能包括 6。提高 mpf 计算的精度将降低遇到此问题的几率.

MPFR 有 mpfr_printf() 允许您控制格式化输出的舍入。例如, mpfr_printf("%.100RZf, avg) 将以 100 位精度打印 avg 并向零舍入。

于 2012-10-09T18:38:48.057 回答