2016-02-10 127 views
3

值正如我们所知,由于数字的二进制表示,该表达式的计算结果为False(至少在Python):使用math.isclose功能与接近0

0.2 + 0.4 == 0.6 

为了能够检查数值误差范围内的平等,模块math提供isclose

import math 
math.isclose(0.2 + 0.4 , 0.6) 

这最后一个表达式产生True预期。

现在为什么下面的表达式再次是False

math.isclose(0.2 + 0.4 - 0.6 , 0.0) 

看来,一切都比较0.0False

math.isclose(1.0e-100 , 0.0) 

回答

8

答案可以通过读取documentation制定。

math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) 

返回真,如果值A和B是相互靠近,否则为假。

根据给定的绝对和相对容差确定两个值是否被认为是接近的。

rel_tol是相对公差 - 它是a和b之间允许的最大差值,相对于a或b的绝对值较大。例如,要将公差设置为5%,请传递rel_tol = 0.05。默认容差是1e-09,这可以确保这两个值在约9个十进制数字内相同。 rel_tol必须大于零。

abs_tol是最小绝对公差 - 用于接近零的比较。 abs_tol必须至少为零。

如果没有出现错误,结果将是:

abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) 

您可以使用默认的公差,这意味着一个相对宽容检查使用。上面的等式清楚地说明了为什么你的表达式评估为false。

考虑问题的最后表达:

math.isclose(1.0e-100 , 0.0) 

插入这些值从文档的表达,我们有

1.0e-100 <= max(1.0e-9 * 1.0e-100, 0.0) 

我认为这应该是显而易见的执行相对公差时比较,使用默认容差,不认为非零值接近零。

对于非常小的值,您应该使用绝对容差。

或者您应该重新编写测试以避免与零比较。

+0

mmph。我确实阅读了文档,并指出我可以设置相对和绝对容差。但我不知何故错过了默认的绝对容差为0.0。也许我应该去睡觉......谢谢大卫 – steffen

+2

为了完整性,[原始PEP](https://www.python.org/dev/peps/pep-0485/#absolute-tolerance-default)解释了为什么绝对公差为0:*“确定值是否”接近“为零所需的绝对容差完全取决于用例。”* –