在使用带有 %d 作为格式说明符的 printf 并给出浮点数作为参数(例如 2.345)时,它会打印 1546188227。所以,我知道这可能是由于将单点浮点精度格式转换为简单的十进制格式。但是当我们使用 %d 作为格式说明符打印 2.000 时,为什么它只打印 0 呢?请帮忙。
6 回答
格式说明符%d
只能与类型int
(和兼容类型)的值一起使用。尝试使用%d
withfloat
或任何其他类型会产生未定义的行为。这是唯一真正适用于此的解释。从语言的角度来看,您看到的输出基本上是随机的。而且您根本无法保证获得任何输出。
如果您仍然有兴趣调查您看到的输出的具体原因(尽管它没有多大意义),则必须执行特定于平台的调查,因为实际行为严重取决于各种实现细节。而且您甚至没有在帖子中提及您的平台。
在任何情况下,作为旁注,请注意不可能将float
值作为可变参数传递给可变参数函数。float
在这种情况下,值总是被转换为double
并作为double
. 因此,在您的情况下,这是double
您尝试打印的值。行为仍然未定义。
到这里,输入,点击2.345
“四舍五入”。观察 64 位十六进制值:4002C28F5C28F5C3
. 观察1546188227
是0x5c28f5c3
。
现在重复 2.00。观察 64 位十六进制值是4000000000000000
PS当你说你给出一个浮点参数时,你的意思显然是你给出了一个双重参数。
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.
如果您试图让它打印整数值,请在调用中将浮点数转换为整数:
printf("ints: %d %d", (int) 2.345, (int) 2.000);
否则,使用浮点格式标识符:
printf("floats: %f %f", 2.345, 2.000);
当您对相应参数使用带有错误格式说明符的 printf 时,结果是未定义的行为。它可以是任何东西,并且可能因一种实现而异。只有正确使用指定的格式才能定义行为。
首先是一个小问题:文字 2.345 实际上是 double 类型,而不是 float,此外,即使是 float,例如文字 2.345f,在用作接受可变数字的函数的参数时也会转换为 double参数,例如 printf。
但是这里发生的是(通常)64 位双精度值被发送到 printf,然后它(通常)将这些位中的 32 位解释为整数值。所以碰巧这些位是零。
根据标准,这就是所谓的未定义行为:编译器可以做任何事情。