对printf输出感到困惑

时间:2012-06-22 06:36:43

标签: c floating-point printf

使用带有%d的printf作为格式说明符并将float作为参数,例如2.345,它打印1546188227.因此,我知道这可能是由于单点浮点精度格式转换为简单的十进制格式。但是当我们用%d作为格式说明符打印2.000时,为什么它只打印0? 请帮忙。

6 个答案:

答案 0 :(得分:4)

格式说明符%d只能用于int类型(和兼容类型)的值。尝试将%dfloat或任何其他类型一起使用会产生未定义的行为。这是真正适用的唯一解释。从语言的角度来看,您看到的输出基本上是随机的。而且你不能保证得到任何输出。

如果您仍然有兴趣调查您看到的输出的具体原因(无论它有多少意义),您将不得不执行特定于平台的调查,因为实际行为主要取决于各种实现细节。你甚至没有在帖子中提到你的平台。

在任何情况下,作为旁注,请注意,不可能将float值作为可变参数传递给可变参数函数。在这种情况下,float值始终转换为double并传递为double。因此,在您的情况下,您尝试打印的值为double。但行为仍未定义。

答案 1 :(得分:1)

转到here,输入2.345,点击“四舍五入”。观察64位十六进制值:4002C28F5C28F5C3。请注意15461882270x5c28f5c3

现在重复2.00。观察到64位十六进制值为4000000000000000

P.S。当你说你给出一个 float 参数时,你的意思是你给出了一个 double 参数。

答案 2 :(得分:1)

ISO / IEC 9899:1999标准7.19.6规定:

If a conversion specification is invalid, the behavior is undefined.239)
If any argument is not the correct type for the corresponding conversion
specification, the behavior is undefined.

答案 3 :(得分:0)

如果您正在尝试使其打印整数值,请在调用中将浮点数转换为整数:

printf("ints: %d %d", (int) 2.345, (int) 2.000);

否则,请使用浮点格式标识符:

printf("floats: %f %f", 2.345, 2.000);

答案 4 :(得分:0)

当您使用具有错误格式说明符的printf作为相应参数时,结果是未定义的行为。它可以是任何东西,可能因实现而异。只有正确使用指定的格式才能定义行为。

答案 5 :(得分:0)

首先是一个小的挑剔:文字2.345实际上是double类型,而不是float,而且,当用作函数的参数时,甚至浮点数(如文字2.345f)也会被转换为double可变数量的参数,例如printf。

但这里发生的是,double值的(通常)64位被发送到printf,然后它(通常)将这些位中的32位解释为整数值。所以恰好这些位是零。

根据标准,这就是所谓的未定义行为:允许编译器做任何事情。