浮点常数
对于以下代码:
#include int main() { float a = 0.7; printf("%.10f %.10f\n", 0.7f, a); return 0; }
我得到的输出是:
0.7000000000 0.6999999881
请解释为什么a
打印为0.6999999881
而文字常量打印为0.7000000000
?
在这种情况下,使用浮点常数是否依赖于编译器?
如果编译器将FLT_EVAL_METHOD
定义为1或2 printf("%.10f",0.7f)
获取“0.7000000000”作为printf("%.10f",0.7f)
打印的字符串printf("%.10f",0.7f)
是正常行为。
实际上,在该模式下,浮点常量可以以超出其类型的精度表示(C11 5.2.4.2.2:9):
除了赋值和强制转换(删除所有额外的范围和精度)之外,具有浮动操作数的运算符产生的值以及通常的算术转换和浮动常量的值将被评估为其范围和精度可能大于所需的格式。类型。
换句话说,打印0.7000000000 0.6999999881 FLT_EVAL_METHOD=2
是下面修改程序的一种可能行为 。
#include #include int main() { float a=0.7; printf("%.10f %.10f FLT_EVAL_METHOD=%d\n",0.7f, a, (int)FLT_EVAL_METHOD); return 0; }
因为编译器将FLT_EVAL_METHOD
定义为2
,所以printf("%.10f %.10f", 0.7f, 0.7)
被视为printf("%.10f %.10f", (double)0.7L, (double)0.7L)
。 同样, printf("%.60Lf %.60Lf\n", (long double)0.7f, (long double)0.7)
相当于printf("%.60Lf %.60Lf\n", 0.7L, 0.7L)
。
你得到不同值的原因是,当你传递给printf(3)
(这是一个vararg函数)作为一个未经检查的参数时,编译器会执行转换为(double)
(和我正在猜测的优化)转换0.7f
文字到0.7D
然后传递给printf
,所以你实际上将两个不同的值传递给printf ,第一个是(double)0.7f
,第二个是变量a
的存储值,转换为a (double)
。