面试问题打印浮点数

以下程序的输出是什么?为什么?

#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个最低有效位,因为它们通常在floatdouble投射之后全部为零。

为了使其绝对清楚,问题中的代码不是有效的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调用的内部未定义行为。