特殊情况下浮点乘法的相关性

use*_*438 5 c floating-point rounding

众所周知,IEEE浮点乘法不是关联的.但是,请考虑a,b和c是32位有符号整数(在C中)的特殊情况:

double da = (double) a;

double db = (double) b;

double dc = (double) c;

现在,da*(db*dc) == (da*db)*dc总是返回1?这里,双精度是64位双精度IEEE foating点.正在使用Round-to-even.

我试着用手几个例子,如a = pow(2, 30) + 1,b = pow(2, 30)+1,c = pow(2, 30) + pow(2, 6),数字大到足以保证会有一些四舍五入参与,因为精确的数学答案不具有代表性.

不幸的是我找不到反例.这个表达式看起来可能会返回0.它可能总是返回1吗?为什么?

use*_*438 3

我设法找到了一个反例。考虑a = pow(2,30) + 1b = pow(2,30) + 1c = pow(2,30) + pow(2, 6) + 1

然后,如果使用舍入到偶数手动计算,我们会得到:

(da*db)*dc == pow(2, 90) + pow(2, 66) + pow(2, 61) + pow(2, 60) + pow(2, 38)

另一方面:

da*(db*dc) == pow(2, 90) + pow(2, 66) + pow(2, 61) + pow(2, 60)

请注意,这两个结果的二进制表示形式仅在最后一位不同。事实上, 90-38=52 ,64 位双精度浮点的二进制表示中的最低有效小数位。