在浮点运算中,当x(1/x) = 1时,是什么时候?

3
我知道在浮点数运算中,由于舍入误差,x(1/x)可能不会精确等于1。这种情况下,最小的正整数x应该是49。
我原以为如果在浮点数运算中1/x可以精确表示,那么x(1/x)应该精确等于1,但是我的教授说实际情况比这复杂,并且举了5作为例子。我就是想不出还有什么其他原因。有人可以给我一个提示吗?提前谢谢!

1
当计算1/x时,可能会出现一个舍入误差(可能为零)。当将其结果乘以x时,可能会出现另一个舍入误差。有时候舍入误差会朝相反的方向发生,从而互相抵消。但有时候则不会。 - undefined
不是一个完整的答案:你可以将问题简化为1<=x<2的情况(忽略次标准和非有限情况)。然后检查1/x的舍入误差最多可以有多少,计算(1/x+error)*x = 1 + error*x并观察error * x何时可能大于epsilon。不确定你是否可以轻松确定哪些x实际上会导致错误,但你可以排除很多情况,例如,我认为x<1.5应该总是舍入回到1。 - undefined
其实,我的假设是错误的。例如,x=561/512 就是一个反例。 - undefined
@EricPostpischil 但是 1.0/5 = 0.2 不是准确的吗?我看到错误可能会互相抵消,但是对于5来说是这种情况吗? - undefined
@InsultedByMathematics 1.0/5 = 0.2 --> 不对。所有有限的二进制IEEE-754数都是有限整数乘以有限次幂的2。0.2不能被一个常见的double精确表示。 - undefined
显示剩余3条评论
1个回答

3
我以为x(1/x)如果1/x可以在浮点运算中精确表示,结果应该是1。
确实,当“1/x可以精确表示”时,这是数学上的等价。
但是我的教授说实际情况比这复杂,并且举了5作为例子。
5不符合“如果1/x可以精确表示”的条件,因为1.0/5.0在常规双精度浮点数中并不是完全等于0.2。可以尝试以下计算:
printf("%.*g\n", DBL_DECIMAL_DIG, 1.0/5.0);

可能不会完全等于1,因为存在舍入误差。
没错。还存在范围问题,因为1.0/DBL_TRUE_MIN通常是无穷大。 0.0、无穷大和NAN是其他通常的嫌疑对象。
还有其他原因吗?
"当计算1/x时,会出现舍入误差(可能为零)。当将其结果乘以x时,会出现另一个舍入误差。有时舍入方向恰好相反,它们会互相抵消。有时则不会。" @Eric Postpischil

有趣的是回答在哪种舍入模式下它会以何种比例被取消,这可以通过对单精度浮点数进行直接实验来计算出来。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接