面试问题打印浮点数

时间:2011-09-25 15:29:41

标签: c floating-point printf

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

  #include <stdio.h>
  int main()
  {
   float a = 12.5;
   printf("%d\n", a);
   printf("%d\n", *(int *)&a);
   return 0;
  }

我的编译器打印0和1095237632.为什么?

3 个答案:

答案 0 :(得分:7)

a引用的内存包含处理器用来表示12.5的位模式。它是如何表示的:IEEE 754。它是什么样子的? See this calculator to find out: 0x4148000。解释为int时是什么? 1095237632.

为什么在不进行投射时会得到不同的值?我不是百分百肯定,但我猜这是因为编译器可以使用calling convention在不同于整数的位置传递浮点参数,所以当printf尝试在字符串后面找到第一个整数参数时,那里没有任何可预测的东西  (或者更可能的是,正如@Lindydancer指出的那样,浮点位可以在int的“右”位置传递,但是因为它们首先通过用零扩展来提升为双重表示,所以printf期望第一个为0 int为。)

答案 1 :(得分:7)

在这两种情况下,都会传递一个表示浮点值的位,并将它们打印为十进制。第二种情况是简单的情况,这里的输出与浮点数的基础表示相同。 (这假设调用约定指定float的值与int的传递方式相同,但不能保证。)

但是,在第一种情况下,当您将float传递给printf等vararg函数时,会将其提升为double。这意味着传递的值将是64位,printf将获取其中的一半(或者可能是垃圾)。在你的情况下,它显然已经获得了32个最低有效位,因为在floatdouble演员之后它们通常都是零。

为了使其绝对清楚,问题中的代码是而不是有效C,因为将值传递给printf与格式说明符不匹配是非法的。

答案 2 :(得分:1)

这是因为floating point representation(参见IEEE 754标准)。

简而言之,一组位,当解释为整数时,在IEEE 755表示中产生12.5浮点值将给出奇怪的值,这与12.5值没有多大的共同点。

来自0的{​​{1}} WRT,这是不正确的printf调用的内部未定义行为。