为什么 printf("%.3f\n", 123456.987654) 打印 123456.984?
Why does printf("%.3f\n", 123456.987654) print 123456.984?
为什么下面的 printf 打印出 123456.984 而不是 123456.988?
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654);
return 0;
}
编辑:我弄错了,正确的printf是:
printf("%.3f\n", 123456.987654f);
该错误肯定与浮点精度有关。它可以用 float
常量复制。
使用浮点常量执行此 printf()
会显示您描述的行为。但是,如果您传递双精度常量,则结果如预期的那样:
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654f); // float: insufficient precision .984
printf("%.3f\n", 123456.987654); // double: better precision .988
// unsuffixed floating point constants are double
return 0;
}
这是由于在转换回十进制时 floating point numbers, that use power of two and fractions of power of twos to represent the numbers. The closest representation corresponding to a number might not be close enough 的内部表示中的近似值。
这种奇怪的舍入行为取决于实现:C 标准没有指定必须使用哪种浮点表示法。
你使用的编译器肯定是基于IEEE 754 standard. On this great web page的,你可以验证一个选定的浮点数是如何使用IEEE单精度编码的:对于123456.987654,几乎使用了所有的位和最接近的位可以用单精度表示的数字是 123456.984375。
在我的电脑上打印出下面的程序(用 gcc 编译)
123456.988
123456.988
123456.984
您问题中的代码实际上是在显示问题,还是涉及到浮动?如果有一个浮点数,那么问题是一个浮点数只有大约 7 个数字的精度。当打印到小数点后 3 位时,最接近您的数字的浮点数约为 123456.984
#include <stdio.h>
#include <stdlib.h>
int main( void)
{
printf("%.3f\n", 123456.987654);
double d = 123456.987654;
printf("%.3f\n", d);
float f = 123456.987654;
printf("%.3f\n", f);
return EXIT_SUCCESS;
}
您遇到的问题似乎是 implementation/compiler-specific(甚至可能与编译或执行有关)。这对我来说是不可复制的。
在在线 Godbolt 编译器和执行器上使用 gcc 9.1 版和 clang 9.0 版,两者的输出都是 123456.988
。
这里是 Link.
为什么下面的 printf 打印出 123456.984 而不是 123456.988?
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654);
return 0;
}
编辑:我弄错了,正确的printf是:
printf("%.3f\n", 123456.987654f);
该错误肯定与浮点精度有关。它可以用 float
常量复制。
使用浮点常量执行此 printf()
会显示您描述的行为。但是,如果您传递双精度常量,则结果如预期的那样:
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654f); // float: insufficient precision .984
printf("%.3f\n", 123456.987654); // double: better precision .988
// unsuffixed floating point constants are double
return 0;
}
这是由于在转换回十进制时 floating point numbers, that use power of two and fractions of power of twos to represent the numbers. The closest representation corresponding to a number might not be close enough 的内部表示中的近似值。
这种奇怪的舍入行为取决于实现:C 标准没有指定必须使用哪种浮点表示法。
你使用的编译器肯定是基于IEEE 754 standard. On this great web page的,你可以验证一个选定的浮点数是如何使用IEEE单精度编码的:对于123456.987654,几乎使用了所有的位和最接近的位可以用单精度表示的数字是 123456.984375。
在我的电脑上打印出下面的程序(用 gcc 编译)
123456.988
123456.988
123456.984
您问题中的代码实际上是在显示问题,还是涉及到浮动?如果有一个浮点数,那么问题是一个浮点数只有大约 7 个数字的精度。当打印到小数点后 3 位时,最接近您的数字的浮点数约为 123456.984
#include <stdio.h>
#include <stdlib.h>
int main( void)
{
printf("%.3f\n", 123456.987654);
double d = 123456.987654;
printf("%.3f\n", d);
float f = 123456.987654;
printf("%.3f\n", f);
return EXIT_SUCCESS;
}
您遇到的问题似乎是 implementation/compiler-specific(甚至可能与编译或执行有关)。这对我来说是不可复制的。
在在线 Godbolt 编译器和执行器上使用 gcc 9.1 版和 clang 9.0 版,两者的输出都是 123456.988
。
这里是 Link.