为什么 printf 在不同的行为中输出浮点数为一位小数的 1.45 和两位小数的 1.445?

Why does printf output float 1.45 with one decimal place, and 1.445 with two decimal places in different behaviors?

printf("%.1f, %.2f", 1.45, 1.445);

输出

1.4, 1.45

1.45 是切片但 1.445 是四舍五入的。

我找到了这个, Why printf round floating point numbers? 其中解释了规范建议对浮点数进行舍入。

编辑: 我用 VS2017(在 C++ 项目中)和 Dev-C 测试了它。

[已编辑:我最初并没有将它们打印到足够可笑的精度水平,所以答案给出了结果背后的不正确推理。]

如果您将它们打印到可笑的精度水平,真相就会浮出水面:

#include <stdio.h>
printf("%20.20f, %20.20f", 1.45, 1.445);

结果:

1.44999999999999995559, 1.44500000000000006217

因此,经过转换,1.45 最终比 1.45 更小,而 1.445 最终比 1.445 更大 .

所以,当然,当我们舍入 1.45 时,它向下舍入,但是当我们舍入 1.445 时,它向上舍入。

double 编码大约 264 个不同的值 正好 .

1.45 和 1.445 都不在 264 值的大集合中,因为这些十进制值不能表示为 dyadic rational 值:一些整数乘以的幂2.

不使用 1.45、1.445,而是使用附近的值:

 1.45  --> 6530219459687219 * 2^-52 or about 1.449999999999999955591079... 
 1.445 --> 6507701461550367 * 2^-52 or about 1.445000000000000062172489...  or 

OP 的 printf() 表现出色并正确地四舍五入这些值。

printf("%.1f\n%.2f", 1.45, 1.445);
1.4     
1.45