判断两个数在舍入到n位有效小数时是否近似相等的函数

2024-07-05 09:47:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我被要求测试由第三方提供的库。已知库精确到n有效数字。任何不太重要的错误都可以安全地忽略。我想写一个函数来帮助我比较结果:

def nearlyequal( a, b, sigfig=5 ):

此函数的目的是确定两个浮点数(a和b)是否近似相等。如果a==b(完全匹配),或者a和b的值在小数点后四舍五入为有效数字时相同,则函数将返回True。

有人能提出一个好的实施方案吗?我写了一个小单元测试。除非你能在我的测试中看到一个bug,否则一个好的实现应该通过以下几点:

assert nearlyequal(1, 1, 5) 
assert nearlyequal(1.0, 1.0, 5) 
assert nearlyequal(1.0, 1.0, 5) 
assert nearlyequal(-1e-9, 1e-9, 5) 
assert nearlyequal(1e9, 1e9 + 1 , 5) 
assert not nearlyequal( 1e4, 1e4 + 1, 5) 
assert nearlyequal( 0.0, 1e-15, 5 ) 
assert not nearlyequal( 0.0, 1e-4, 6 ) 

附加说明:

  1. 值a和b的类型可以是int、float或numpy.float64。值a和b将始终为同一类型。转换不能在函数中引入额外的错误,这一点很重要。
  2. 让我们保持这个数值,这样转换成字符串或使用非数学技巧的函数就不理想了。这个程序将由一个数学家审核,他希望能够证明这个函数做了它应该做的事情。
  3. 速度。。。我要比较很多数字,所以越快越好。
  4. 我有numpy,scipy和标准库。其他的东西对我来说都很难得到,特别是对于这个项目的一小部分。

Tags: 函数目的numpytrue类型def错误not
3条回答

这是一张照片。

def nearly_equal(a,b,sig_fig=5):
    return ( a==b or 
             int(a*10**sig_fig) == int(b*10**sig_fig)
           )

numpy.testing(源here) )中有一个函数assert_approx_equal,这可能是一个很好的起点。

def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True):
    """
    Raise an assertion if two items are not equal up to significant digits.

    .. note:: It is recommended to use one of `assert_allclose`,
              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
              instead of this function for more consistent floating point
              comparisons.

    Given two numbers, check that they are approximately equal.
    Approximately equal is defined as the number of significant digits
    that agree.

从Python 3.5开始,执行此操作的标准方法(使用标准库)是使用^{}函数。

它有以下签名:

isclose(a, b, rel_tol=1e-9, abs_tol=0.0)

使用绝对误差公差的示例:

from math import isclose
a = 1.0
b = 1.00000001
assert isclose(a, b, abs_tol=1e-8)

如果需要精度为n有效数字,只需将最后一行替换为:

assert isclose(a, b, abs_tol=10**-n)

相关问题 更多 >