我在 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
时它确实工作正常.对于不同p1
和 p2
问题可能会或可能不会发生。我发现这种行为非常奇怪,导致非常不可靠的结果。
可能与 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/