testing浮点相等
有没有一个函数来testingpython中的浮点近似相等? 就像是,
def approx_equal(a, b, tol): return abs(a - b) < tol
我的用例类似于Google的C ++testing库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))
- 对于testing数字,有
nose.tools.assert_almost_equal
和等价unittest.assertAlmostEqual
- 为了testing数字或数组,有
numpy.testing.assert_allclose
- 为了比较数字,从Python 3.5
math.isclose
,按照PEP 485进行math.isclose
计算。 - 为了比较数字或数组,有
numpy.allclose
。
另一种方法是计算两个数字的相对变化 (或相对差异),这两个数字“用于比较两个数量,同时考虑被比较事物的”大小“。 Wikipedia文章中提到的两个公式可以用于比较,如Python中的以下内容,它们还处理一个或两个被比较的值为零的情况:
def approx_equal(a, b, tol): return abs(ab) <= max(abs(a), abs(b)) * tol def approx_equal(a, b, tol): return abs(ab) <= (abs(a)+abs(b))/2 * tol
两种情况下的计算值都是无单位的分数。 在第一种情况下,基准值是两个数字的最大绝对值,第二种情况是它们的平均绝对值。 文章更详细地讨论了每个细节以及它们的优缺点。 后者可以变成一个百分比的差异,如果乘以100比较( tol
成为一个百分比值)。 请注意,文章提出,如果变化的价值“本身就是一个百分比,最好用百分点来谈论它的变化” – 即绝对变化。
这两种方法(显然)都需要更多的计算,而不是简单地取两个数的差值的绝对值,这可能是一个考虑因素。
有没有一个函数来testingpython中的浮点近似相等?
不能有一个函数,因为定义取决于上下文。
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
可能更合适。
另外,还有一直stream行的
def eq( a, b, eps=0.0001 ): return abs(math.log( a ) - math.log(b)) <= eps
哪个可能更合适。
我看不出你怎么可以要求一个 (单一的)function结合所有的mathselect。 因为它取决于应用程序。
如果我是你,我只是使用你写的东西,或者把它放在一个单独的模块中(或许你需要的其他工具,Python没有实现),或者在任何代码所需的顶部。
您也可以使用lambdaexpression式(我最喜欢的语言function之一,但可能不太清楚):
approx_equal = lambda a, b, t: abs(a - b) < t
比较花车平等通常是一个坏主意。 即使有你使用的宽容function,这实际上不是你想要做的。
如果你想使用浮点数,一个合理的select是重构你的algorithm来使用不等式, a < b
因为这更有可能做你期望的,更less的漏报或肯定的,更重要的是,我们不得不猜测他们必须是平等的。
如果你不能这样做,另一个select是使用一个确切的表示。 如果你的algorithm仅由算术运算( +
, -
, *
和/
)组成,那么你可以使用由fractions.Fraction
提供的合理的represntation,或者可以是decimal.Decimal
是你想要的(例如,用财务计算) 。
如果你的algorithm不能用任意的精度表示容易地expression出来,另一个select就是用区间algorithm明确地pipe理舍入误差,例如用这个模块 。
根据教程 :
…虽然数字不能接近其预期的精确值,但是round()函数对于后置四舍五入可能是有用的,这样带有不精确值的结果可以相互比较。
因此,这是我在Python中定义“isclose”函数的方式:
def isclose(a, b, ndigits): return round(ab, ndigits) == 0
我通常使用5作为ndigits
; 但是,这取决于您期望的精度。