是否有在python中测试浮点近似相等的函数?像,
def approx_equal(a, b, tol):
return abs(a - b) < tol
我的用例类似于Google的C ++测试库gtest.h定义EXPECT_NEAR
。
以下是一个例子:
def bernoulli_fraction_to_angle(fraction):
return math.asin(sqrt(fraction))
def bernoulli_angle_to_fraction(angle):
return math.sin(angle) ** 2
def test_bernoulli_conversions():
assert(approx_equal(bernoulli_angle_to_fraction(pi / 4), 0.5, 1e-4))
assert(approx_equal(
bernoulli_fraction_to_angle(bernoulli_angle_to_fraction(0.1)),
0.1, 1e-4))
答案 0 :(得分:51)
math.isclose
。numpy.allclose
。numpy.testing.assert_allclose
答案 1 :(得分:19)
另一种方法是计算两个数字的relative change(或相对差异),“用于比较两个数量,同时考虑被比较事物的'大小'”。维基百科文章中提到的两个formulas可用于比较,如Python中的以下内容,它也处理被比较的一个或两个值为零的情况:
def approx_equal(a, b, tol):
return abs(a-b) <= max(abs(a), abs(b)) * tol
def approx_equal(a, b, tol):
return abs(a-b) <= (abs(a)+abs(b))/2 * tol
两种情况下的计算值都是无单位分数。在第一种情况下,基线值是两个数字的最大绝对值,在第二种情况下,它是它们的平均绝对值。本文将更详细地讨论每个问题以及它们的优缺点。如果在比较之前乘以100,后者可以变成percentage difference(tol
变为百分比值)。请注意,文章建议如果变化值“本身就是一个百分比,最好通过使用百分点来谈论它的变化” - 即绝对变化。
这两种方法(显然)需要比简单地取两个数的差值的绝对值更多的计算,这可能是一个考虑因素。
答案 2 :(得分:8)
是否有在python中测试浮点近似相等的函数?
不能有 a 函数,因为定义取决于上下文。
def eq( a, b, eps=0.0001 ):
return abs(a - b) <= eps
并不总是有效。有些情况
def eq( a, b, eps=0.0001 ):
return abs( a - b ) / abs(a) <= eps
可能更合适。
另外,总是很受欢迎。
def eq( a, b, eps=0.0001 ):
return abs(math.log( a ) - math.log(b)) <= eps
哪个可能更合适。
我看不出你如何要求 a (单一)功能结合所有数学选择。因为它取决于应用程序。
答案 3 :(得分:5)
如果我是你,我只会使用您编写的内容,并将其放在一个单独的模块中(可能与您需要的其他实用程序,Python没有实现)或在任何代码要求的顶部它
您还可以使用lambda表达式(我最喜欢的语言功能之一,但可能不太清楚):
approx_equal = lambda a, b, t: abs(a - b) < t
答案 4 :(得分:4)
比较花车的平等性通常是一个坏主意。即使使用了您正在使用的容差功能,这也不是您想要做的。
如果你想使用浮点数,一个合理的选择就是重构你的算法以使用不等式a < b
,因为这更有可能达到你的预期,假阴性或阳性更少,最重要的是,这意味着你不必猜测他们必须达到平等的程度。
如果你不能这样做,另一种选择是使用精确的表示。如果您的算法仅由算术运算(+
,-
,*
和/
组成),那么您可以使用fractions.Fraction
提供的合理重新定义,或者decimal.Decimal
可能是你想要的(例如,财务计算)。
如果您的算法无法使用任意精度表示轻松表达,则另一种选择是使用区间运算明确管理舍入误差,例如使用this module。
答案 5 :(得分:0)
根据the tutorial:
...虽然数字不能接近预期的精确值,但round()函数可用于后舍入,因此不精确值的结果可以相互比较......
因此,这是我在Python中定义“isclose”函数的方式:
def isclose(a, b, ndigits):
return round(a-b, ndigits) == 0
我通常使用5作为ndigits
;但是,它取决于您期望的精度。