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 ; 但是,这取决于您期望的精度。