double a = 3.1456;
int aa=2.0;
printf ("%f \n",a );
printf("%f \n",aa);
答案是3.145600 ,3.145599.
我尝试了不同的a值,输出aa似乎与a有一些关系。
我很迷惑。什么原因?
〜
〜
〜
〜
答案 0 :(得分:2)
printf( "%f", ... )
期望double
作为参数,但是yu传递一个整数。那是UB。在您的情况下,作为sizeof(double) > sizeof(int)
,第二个printf()可能从堆栈中读取前一次调用中“仍然存在”的一些字节。如果你在两者之间添加了一些其他的功能,那么结果将是别的。但是因为它是UB,未定义是这样的,我发生的任何事情
答案 1 :(得分:2)
Ingo Leonhardt说你的程序的行为是未定义的 - 输出在优化或不同的架构/编译器下不会保持一致。
但是,在这种情况下,您看到3.1456变异为3.145599的具体原因是可以解释的。可以推断,您的架构使用IEEE-754 8字节double
和4字节小端int
。最近的8字节双精度到3.1456的十六进制表示为:
0x40092a305532617c
其中符号为0
,指数字段为0x400
(表示指数为1),尾数字段为0x92a305532617c
(表示十六进制尾数为0x1.92a305532617c)。如果用4字节整数2覆盖它的低4字节,那么你得到:
0x40092a3000000002
这个符号和指数没有变化,但是尾数已经变为0x1.92a3000000002,或者比原始值小0x0.000005532617a。如果指数为1,则表示差值为0x0.00000aa64c2f4,十进制为~0.000000634766。当你从3.1456中减去它时,你会得到~3.145599365234,它会转到3.145599。