printf<浮动时的舍入问题

时间:2017-07-14 14:04:33

标签: c floating-point

有人可以解释为什么C' printf在第二种情况下正在逐渐减少?

printf("%.03f", 79.2025); /* "79.203" */
printf("%.03f", 22.7565); /* "22.756" */

3 个答案:

答案 0 :(得分:6)

OP的帖子提示:

printf("%.03f", 79.2025); /* "79.203" */
printf("%.03f", 22.7565); /* "22.756" */

为什么一个值四舍五入而另一个值下降?

79.202522.7565等数字在您的系统上不能完全代表double。而是编码附近的值。

2个可能的完全 doubles

79.2025000000000005684341886080801486968994140625
22.756499999999999062083588796667754650115966796875

这是因为使用binary floating point编码。大多数系统使用二进制浮点数,尽管C确实允许基数:16,10和其他2的幂。(我从未使用过“其他2次幂”系统。)

将这两个值打印到最接近0.001的printf("%.03f"...指示位于下方,与OP的结果相符。

79.203  // 79.20250000000000056... rounds up   as 50000000000056... > 50000000000000...
22.756  // 22.75649999999999906... rounds down as 49999999999906... < 50000000000000...

以下内容也很有趣。 1.0625和1.1875都完全编码为double。然而,由于通常的“圆形关系甚至”规则,一个通常会围绕而另一个向下舍入。根据不同的情况,您的输出可能会有所不同,但以下输出很常见。

printf("%.03f", 1.0625); /* "1.062" */
printf("%.03f", 1.1875); /* "1.188" */

使用不同精度二进制浮点类型更改基本问题:FP在表单中的代码中分配了一个十进制值x.xxx5很少有匹配的确切值。其中约50%将超过x.xxx5而另一个则更少。

答案 1 :(得分:1)

printf("%.03f", 79.2025); /* "79.203" */

printf("%.03f", 22.7565); /* "22.756" */

点后3个字符

printf("%6.3f", 79.2025);  /* "79.203" */

printf("%6.3f", 22.7565);  /* "22.756" */

2字符+。 + 3字符= 6个字符

答案 2 :(得分:0)

这是common behaviour in floating point precision;它并不完美,因为用于表示值的位数有限。在某些时候,小数位变得非常小,超出了给定位宽可用的精度。

也许寻求更高分辨率的小数,例如long double