C浮点数每次执行时都会更改%d值

时间:2016-07-08 12:00:31

标签: c floating-point computer-science precision

我尝试使用%d打印浮动(我知道不应该这样做)。 但每次重新运行可执行文件时,它会给出不同的值) 我的问题是:为什么打印值每次都会改变? 我的系统:Ubuntu 14.04(64位) 编译:4.8.4 这是代码:

#include<stdio.h>

int main(){
  float b = 12.3456;

  printf("%d\n",b);

}

示例输出:

4bh1@mybox:~/C-fi$ ./test 
-1629995944
4bh1@mybox:~/C-fi$ ./test 
1147348376
4bh1@mybox:~/C-fi$ ./test 
-1746005432
4bh1@mybox:~/C-fi$ ./test 
510102216
4bh1@mybox:~/C-fi$ 

3 个答案:

答案 0 :(得分:8)

使用printf的错误格式说明符是undefined behavior的典型示例。这意味着行为是不可预测的,并且不能依赖于从一次运行到下一次运行的一致性。它可能会崩溃,它可能会打印随机值,或者它似乎可以正常工作。

实际发生的是有问题的编译器和体系结构的实现细节。但除非你真的在编写编译器,否则在挖掘它时没有多大用处。

如果您熟悉汇编程序,可以查看已编译的代码以查看它生成的指令。但请记住,不同的编译器(即使是具有不同优化设置的相同编译器)也很可能生成不同的汇编。

答案 1 :(得分:7)

可能通过FPU寄存器传递浮点值,但printf()尝试从其他地方读取整数,它希望看到整数(堆栈或其他寄存器)。那个地方的内容没有具体说明。严格说(正如@dbush所提到的)你的代码会导致未定义的行为。

答案 2 :(得分:1)

如评论中所示,这听起来像是未定义的行为,它解释了(好吧,某种程度上)正在发生的事情。

如果你想阅读一个浮点数的内部表示,或者你想对数字做一些低级别的黑客攻击,那么这样做的方法很简单,例如:

union {
    float f;
    int i;
} n;

n.f = 12.3456;
printf("%d\n", n.i); // should be the same number each time

请注意,这只适用于floatint在您的系统上具有相同尺寸的情况,但适用于大多数人。如果您想确定,可以添加assert(sizeof(float) == sizeof(int))

相关问题