浮点除法的一致性

dev*_*vtk 3 python floating-point

众所周知,浮点值不能准确表示每个十进制值。因此,1/3 的浮点值不完全是 1/3。因此,通常不建议直接比较浮点值。

但是,在此应用程序中,我试图确定两个分数 a / b 和 c / d 是否相等。如果是,则存在整数 e 和 f 使得a * e = c * fb * e = d * f。假设 a、b、c、d、e、f 都是正整数,可以精确地用浮点值表示。

在实践中,简单地比较a/bc/d工作,但它保证工作?Python 和/或 IEEE-754 中有什么东西可以保证这样的方案有效吗?

示例代码(显示此方案适用于合理数量的值):

a = 1.0
b = 3.0
for c in xrange(1, 999):
    assert a / b == (a * c) / (b * c)
Run Code Online (Sandbox Code Playgroud)

如果这不能保证,是否有一个反例,其值为 a、b、c、d,使得 a/b = c/d(在数学中)但 Python 无法比较a / b == c / d?同样,这些都是 Python 可以在其浮点值中准确表示的正整数。

use*_*ica 5

指定 IEEE 754 除法的行为就像您计算除法的精确结果然后对精确结果进行四舍五入一样。如果a/bc/d在精确算术中具有相同的值,那么由于 IEEE 754 舍入是一致且确定的,a/b并且c/d在 IEEE 754 浮点中必须具有相同的结果。

不过,这仅适用于当a/bc/d确实在精确算术中具有相同的值时。在舍入误差abc,或者d可以抛出这一关。此外,反过来也不成立。如果a/b == c/d在浮点,并不意味着a/bc/d在精确的算法相同。


与其处理浮点舍入,为什么不坚持使用整数呢?

a*d == b*c
Run Code Online (Sandbox Code Playgroud)

可以在未舍入的整数算术中完成。或者,为什么不使用精确的有理类型?

from fractions import Fraction

Fraction(a, b) == Fraction(c, d)
Run Code Online (Sandbox Code Playgroud)