【发布时间】:2024-01-23 09:40:01
【问题描述】:
对于浮点值,是否保证a + b与1b + a相同?
我相信这在 IEEE754 中得到了保证,但是 C++ 标准并未指定必须使用 IEEE754。唯一相关的文字似乎来自 [expr.add]#3:
二元+运算符的结果是操作数之和。
数学运算“sum”是可交换的。然而,数学运算“sum”也是关联的,而浮点加法绝对是not关联的。所以,在我看来,我们不能得出结论,数学中“sum”的交换性意味着这句话指定了 C++ 中的交换性。
脚注 1:
“相同”与按位相同,例如 memcmp 而不是 ==,以区分 +0 和 -0。 IEEE754 将+0.0 == -0.0 视为真,但也有符号零的特定规则。 +0 + -0 和 -0 + +0 在 IEEE754 中都产生 +0,对于添加具有相等幅度的相反符号值也是如此。遵循 IEEE 语义的== 将隐藏有符号零的非交换性(如果这是标准)。
此外,如果任一输入为 NaN,则 a+b == b+a 在 IEEE754 数学中为假。
memcmp 将说明两个 NaN 是否具有相同的位模式(包括有效负载),尽管我们可以将 NaN 传播规则与有效数学运算的交换性分开考虑。
【问题讨论】:
-
std::strtod("nan")+0.0 == 0.0+std::strtod("nan")为假。但我怀疑这就是你的意思。 -
为什么要限制自己使用浮点数?不用多想,我不认为 C++ 要求整数加法是可交换的(例如溢出结果可能是不可交换的)。
-
@StephenCanon:这似乎取决于您对未定义行为的看法。对于不引出 UB 的程序,整数加法是可交换的,并且程序是否引出 UB 不能取决于整数加法的可交换性。
-
询问
a+b == b+a是否与询问是否可交换不一样,因为==与memcmp 不同。在类似于 IEEE754 的系统中,最可能的非交换性(如某些软件-FP 仿真)可能是有符号零或不同的NaN 有效载荷。 (例如,0 + -0可能总是使用左侧操作数的符号,而在 IEEE754 中总是使用+0。)但它很可能仍然实现-0 == +0IEEE 语义。 (此外,如果 a 或 b 为 NaN,则a+b == b+a对于 IEEE754 为 false。同样,memcmp 实际上会检查交换性)。
标签: c++ floating-point language-lawyer commutativity