C ++中的浮点加法是否可交换?

时间:2014-06-27 01:35:03

标签: c++ floating-point language-lawyer

对于浮点值,是否保证a + b == b + a

我相信这在IEEE754中是有保证的,但是C ++标准没有规定必须使用IEEE754。唯一相关的文本似乎来自[expr.add]#3:

  

binary +运算符的结果是操作数的总和。

数学运算“和”是可交换的。但是,数学运算“sum”也是关联的,而浮点加法肯定是关联的。因此,在我看来,我们无法得出结论,数学中“和”的交换性意味着这个引用指的是C ++中的交换性。

3 个答案:

答案 0 :(得分:18)

不,C ++语言通常不会对硬件提出这样的要求。只定义了运算符的关联性。

各种疯狂的事情发生在浮点运算中。也许,在某些机器上,将零加到非正规数会产生零。可以想象,在将零值寄存器添加到存储器中的非正规的情况下,机器可以避免更新存储器。可能是一个非常愚蠢的编译器总是把LHS放在内存中,将RHS放在寄存器中。

但是,请注意,如果您要对所获得的操作进行任何控制,那么具有非交换添加的计算机将需要专门定义表达式如何映射到指令。左侧是进入第一个机器操作数还是进入第二个机器操作数?

这样的ABI规范,同时提到表达和指令的构造,将是非常病态的。

答案 1 :(得分:15)

甚至不需要a + b == a + b。其中一个子表达式可以比另一个子表达式更精确地保持加法结果,例如当使用多个加法项时需要将其中一个子表达式临时存储在存储器中,而另一个子表达式可以保存在寄存器中(精度更高。)

如果无法保证a + b == a + b,则无法保证a + b == b + a 。如果a + b每次都不必返回相同的值,并且值不同,则其中一个必然将不等于b + a的一个特定评估。< / p>

答案 2 :(得分:11)

C ++标准非常明确地保证IEEE 754.该库确实支持IEC 559(基本上只是IEC 754标准的IEC版本),所以你可以检查底层实现是否使用IEEE 754 / IEC 559(当它确实如此时,你可以依赖它保证的内容)。

在大多数情况下,C和C ++标准假定这些基本操作将被实现,但底层硬件可以工作。对于像IEEE 754这样常见的东西,它们会让你检测它是否存在,但仍然不需要它。