我需要显示整数平均计算结果的前 100 位有意义的数字。系列整数存储在 mpz_t 类型的数组中,然后将其求和到 mpq_t 并除以另一个 mpq_t(计数)
代码:
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);
Run Code Online (Sandbox Code Playgroud)
最后一行的显示,假设 sum = 2, count = 3 是错误的。它在大约 10-15 位数字后上限并用 0 填充。对于 (2/3),它是 0.66666666670000...
所以有两件事:
因此对于 (2/3) 期望的输出是:
0.666...666(一百个6,末尾也有6)
使用 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,并向零舍入。