0
double a = 3.1456;

int aa=2.0;      

printf ("%f \n",a );    
printf("%f \n",aa);

答案是3.145600 ,3.145599. 我尝试了不同的 a 值,并且输出 aa 似乎与 a 有某种关系。我很困惑。什么原因?~
~
~
~

4

2 回答 2

2

printf( "%f", ... )期望 adouble作为参数,但 yu 传递一个整数。那是UB。在您的情况下, as sizeof(double) > sizeof(int),第二个 printf() 可能会从堆栈中读取一些字节,这些字节从上一次调用中“仍然存在”。如果您在两者之间添加了一些其他功能,结果将是其他东西。但是因为它是 UB,所以它没有被定义为这样,我发生的任何事情

于 2013-07-30T09:44:16.433 回答
2

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

但是,在这种情况下,您看到 3.1456 突变为 3.145599 的具体原因是可以解释的。可以推断,你的架构使用了 IEEE-754 8-byte doubles 和 4-byte little-endian ints。最接近 3.1456 的 8 字节双精度的十六进制表示是:

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。

于 2013-07-30T11:18:53.507 回答