面试问题打印浮点数
以下程序的输出是什么?为什么?
#include int main() { float a = 12.5; printf("%d\n", a); printf("%d\n", *(int *)&a); return 0; }
我的编译器打印0和1095237632.为什么?
在这两种情况下,您都传递一个表示浮点值的位,并将它们打印为十进制。 第二种情况是简单的情况,这里的输出与浮点数的底层表示相同。 (这假定调用约定指定了float
的值以与int
相同的方式传递,这是不可保证的。)
但是,在第一种情况下,当您将float
传递给类似printf
的vararg函数时,它会被提升为double
。 这意味着传递的值将是64位, printf
将获取其中的一半(或者可能是垃圾)。 在你的情况下,它显然已经获得了32个最低有效位,因为它们通常在float
到double
投射之后全部为零。
为了使其绝对清楚,问题中的代码不是有效的C,因为将值传递printf
格式说明符不匹配的printf
是非法的。
由a
引用的存储器保持处理器用来表示12.5的位模式。 它是如何表示的: IEEE 754 。 它是什么样子的? 请参阅此计算器以查找:0x4148000 。 解释为int时是什么? 1095237632。
为什么在不进行投射时会得到不同的值? 我不是100%肯定,但我猜它是因为编译器可以使用一个调用约定 ,它将浮点参数传递到与整数不同的位置,所以当printf尝试在字符串后面找到第一个整数参数时,没有什么可预测的那里。
(或者更可能的是,正如@Lindydancer指出的那样,浮点数可以在’右’的位置传递给int,但是因为它们首先通过用零扩展来提升为双重表示,所以printf期望第一个为0 int是。)
这是因为浮点表示 (参见IEEE 754标准)。
简而言之,一组位,当解释为整数时,在IEEE 755表示中使12.5浮点值将给出奇怪的值,这与12.5值没有多大的共同点。
从printf("%d\n", a)
WRT到0
,这是不正确的printf调用的内部未定义行为。