先贴上我在 v2ex 上问的这个问题:
让我疑惑的代码:
运行截图:
运行环境:
在这个环境下每一次运行出来的结果都是一样的。
然后切换到 Linux 的环境:
运行截图:
运行环境:
在 Linux 这个环境下每一次的运行结果都是不一样的。
然后我想弄清楚的是,这个问题是不是就是将 double
类型的值在内存中截掉一半然后打印出来(截掉前半段)。
所以我们用一个程序来验证一下:
运行结果:
(double) a * b = 0x40 1a 66 66 60 00 00 00, 截断四个字节后 0x60 00 00
00 = 1610612736
我利用这个工具网将
16 进制的数转换了一下,使用 IEEE754 标准,如下:
发现在 Windows 下,C 语言 %d 打印 double 的结果确实是把 double
类型在内存中的值截掉一半然后打印。
对于 Linux 系统中的值,我在 v 站中得到了这样的解释:
在 x86_64
下,整数和指针参数通过通用寄存器传递,浮点数通过浮点数寄存器传递。
这里调用时往浮点数寄存器写入了参数,但函数里面却去通用寄存器里读取,所以结果是随机的。
在 x86 下,参数都通过栈传递,结果应该是 double 截断的结果。
但是,新的问题又来了,为什么第二次打印 a.num
的值一直是
10
呢?
也罢,暂时把这个问题先搁置在这里,汇编编译出来的代码如下: