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吗?为什么?
我设法找到了一个反例。考虑a = pow(2,30) + 1,b = pow(2,30) + 1,c = 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 位双精度浮点的二进制表示中的最低有效小数位。