printa(“%f”,aa)当aa的类型为int 时

double a = 3.1456; int aa=2.0; printf ("%f \n",a ); printf("%f \n",aa); 

答案是3.145600 ,3.145599. 我尝试了不同的a值,输出aa似乎与a有一些关系。 我很迷惑。 什么原因? 〜


Ingo Leonhardt说你的程序行为未定义是正确的 – 输出在优化或不同架构/编译器下不会保持一致。

但是,在这种情况下,您看到3.1456变异为3.145599的具体原因是可以解释的。 可以推断,您的架构使用IEEE-754 8字节double s和4字节little-endian int 。 最近的8字节双精度到3.1456的hex表示forms为:

 0x40092a305532617c 

符号为0 ,指数字段为0x400 (表示指数为1),尾数字段为0x92a305532617c (表示hex尾数为0x1.92a305532617c)。 如果用4字节整数2覆盖它的低4字节,那么你会得到:

 0x40092a3000000002 

这有符号和指数不变,但尾数已更改为0x1.92a3000000002,或小于原始的0x0.000005532617a。 如果指数为1,则表示差值为0x0.00000aa64c2f4,十进制为~0.000000634766。 当你从3.1456中减去它时,你会得到~3.145599365234,它会转到3.145599。

printf( "%f", ... )需要double参数,但是yu传递一个整数。 那是UB。 在你的情况下,作为sizeof(double) > sizeof(int) ,第二个printf()可能会从堆栈中读取前一次调用中“仍然存在”的一些字节。 如果你在两者之间添加了一些其他function,那么结果将是另外的。 但是因为它是UB,所以没有定义如此,任何我发生的事情