Python问题与舍入

For*_*zaa 1 python floating-point rounding

我在Python 2.7中有一个舍入问题导致意外输出.我试图得到p1和p2的总和达到0.6或更少的组合.

from itertools import product
P = []
p1 = [0.0,0.2,0.4,0.6]
p2 = [0.0,0.2,0.4,0.6] 
for p11,p22 in product(p1,p2):
    if p11+p22 <= max(p1):    
        P.append((p11,p22))
Run Code Online (Sandbox Code Playgroud)

但是,当我运行它时,它不包括p11 + p22 = 0.6的所有值:

[(0.0, 0.0),
 (0.0, 0.2),
 (0.0, 0.4),
 (0.0, 0.6),
 (0.2, 0.0),
 (0.2, 0.2),
 (0.4, 0.0),
 (0.6, 0.0)]
Run Code Online (Sandbox Code Playgroud)

我设置时它可以正常工作p11+p22 <= max(p1)+0.01.对于不同的p1p2可能会或可能不会出现问题.我发现这种行为非常奇怪,导致非常不可靠的结果.

它可能与浮动精度问题有关.在我看来,这种行为不应该存在于Python中,因为R和Matlab也没有这种行为.这有什么简单的方法吗?

Mar*_*oma 5

怎么了?

计算机具有数字的内部表示.在大多数情况下,这些表示具有固定的位数.这导致仅可表示固定数量的数字.例如,您可能知道像C这样的语言具有整数的最大值.

类似地,您无法存储某些浮点数的精确表示.由于计算机使用基数为2,因此基数10中有一些数字具有短的有限表示但二进制数字很长.有关更多详细信息,请参阅IEEE 754.

怎么能"固定"?

这里没有什么可以解决的,因为一切都像指定的那样工作.但你必须知道这些类型的问题.当您意识到存在问题的事实时,有两种策略可以解决它.

使用epsilons( - >不要与确切的数字进行比较,但要检查数字是否在数字周围的非常小的区间内.此区间的长度通常称为"epsilon")或使用任意精度表示(请参阅fractions.第二种只有当你可以影响数字如何被放入程序时才有效,例如

from itertools import product
from fractions import Fraction
P = []
p1 = [Fraction(0.0), Fraction(2, 10), Fraction(4, 10), Fraction(6, 10)]
p2 = [Fraction(0.0), Fraction(2, 10), Fraction(4, 10), Fraction(6, 10)]
for p11, p22 in product(p1, p2):
    if p11+p22 <= max(p1):
        P.append((p11, p22))
Run Code Online (Sandbox Code Playgroud)

也可以看看