Python 的四舍五入问题

标签 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))

但是,当我运行它时,它不包括 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)]

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

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

最佳答案

发生了什么?

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

类似的,你不能存储一些 float 的精确表示。由于计算机使用二进制,因此有些以 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))

另见

关于Python 的四舍五入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33845435/

相关文章:

python - 如何在 python pandas 中使用两个列值创建 url 列数据框?

javascript - 如何检查在 Jinja2 HTML 模板中选择了一组单选按钮中的哪个单选按钮?

c - 1/(2^x) 可以用 C 编程语言表示的最小精确表示是什么?

linux - 比较两个数字,但如果条件不能正常工作

c++ - 加倍加倍是否会导致0.0?如果没有,该如何实现?

javascript - 如何在圆形 slider 中显示标签..?

python - 四舍五入到任何给定值 python

python - 高效递归迭代器: Possible?

python - 在 Spark 中更新数据框列

java - 如何避免 double 舍入到 0