我正在32位和64位平台上编译并运行以下程序:
int main()
{
double y = 8.34214e08;
double z = 1.25823e45;
return y * z == 8.34214e08 * 1.25823e45;
}
在64位中,结果是预期的(值相同,并且退出代码为非零),在32位中,似乎在编译时计算的值,比较的右侧和左侧之间存在少许差异边在运行时计算。
这是编译器中的错误还是有逻辑上的解释?
编辑:这与为什么将double和float进行比较会导致意外结果不同?因为这里所有的值都是双精度的。
IEEE-754允许以更高的精度进行中间计算(强调我的意思)。
(IEEE-754:2008)“语言标准还应该定义并要求实现提供提供属性,该属性分别允许或不允许对块进行值更改优化。这些优化可能包括但不限于: [...]在表达评估中使用更广泛的中间结果。”
例如,在IA-32上,双精度值可以更高的精度(80位而不是64位)存储在x87 FPU寄存器中。因此,您实际上是在比较以双精度进行的乘法和以双精度进行的乘法。
例如,在结果为x64的x64上1
(不使用x87 FPU而是使用SSE),添加使用x87的gcc
选项-mfpmath=387
会使结果0
在我的计算机上更改为。
如果您想知道C是否也允许这样做,那就是:
(C99,6.3.1.p8)“浮动操作数的值和浮动表达式的结果的表示精度和范围可能比类型所需的精度和范围更大。”
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句