用于确定两个数字四舍五入为十位十进制数时几乎相等的函数 [英] Function to determine if two numbers are nearly equal when rounded to n significant decimal digits

查看:203
本文介绍了用于确定两个数字四舍五入为十位十进制数时几乎相等的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

pre $ def $ a $ b $ sig $ g

这个函数的目的是确定两个浮点数(a和b)是否近似相等。如果a == b(精确匹配),或者如果a和b在用十进制写成四舍五入到 sigfig 有效数字时,函数将返回True。

有人可以提出一个好的实现吗?我写了一个小单元测试。除非你能在我的测试中看到一个错误,那么一个好的实现应该通过以下几点:

  assert almostequal(1,1,5 )
assert almostequal(1.0,1.0,5)
assert almostequal(1.0,1.0,5)
assert almostequal(-1e-9,1e-9,5)
assert (1e9,1e9 + 1,5)
几乎不等于(1e4,1e4 + 1,5)
几乎等于(0.0,1e-15,5)
断言几乎不等于0.0 ,1e-4,6)

其他注意事项:


  1. 值a和b可能是int,float或numpy.float64类型。值a和b将始终是相同的类型。转换不会在函数中引入额外的错误是至关重要的。
  2. 让我们保留这个数值,所以转换为字符串或使用非数学技巧的函数并不理想。这个程序将由一个数学家谁将要能够证明该功能做它应该做的事情审计。

  3. 速度...我必须比较大量数字,越快越好。
  4. 我有numpy,scipy和标准库。其他任何东西都难以获得,特别是对于这样一小部分的项目。


解决方案

numpy.testing (source assert_approx_equal / numpy / numpy / blob / 1225aef37298ec82048d0828f6cb7e0be8ed58cc / numpy / testing / utils.py#L513rel =nofollow noreferrer> here)这可能是一个很好的起点。
$ b $ pre $ def $ assert_approx_equal(actual,desired,significant = 7,err_msg ='',verbose = True):

如果两个项目不等于有效数字,则引发一个断言

..注意:建议使用`assert_allclose`,
`assert_array_almost_equal_nulp ``或`assert_array_max_ulp`
代替这个函数来获得更一致的浮点数
比较

给定两个数字,检查它们是否大致相等
大致相等定义为同意的有效位数


I have been asked to test a library provided by a 3rd party. The library is known to be accurate to n significant figures. Any less-significant errors can safely be ignored. I want to write a function to help me compare the results:

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

The purpose of this function is to determine if two floating-point numbers (a and b) are approximately equal. The function will return True if a==b (exact match) or if a and b have the same value when rounded to sigfig significant-figures when written in decimal.

Can anybody suggest a good implementation? I've written a mini unit-test. Unless you can see a bug in my tests then a good implementation should pass the following:

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 ) 

Additional notes:

  1. Values a and b might be of type int, float or numpy.float64. Values a and b will always be of the same type. It's vital that conversion does not introduce additional error into the function.
  2. Lets keep this numerical, so functions that convert to strings or use non-mathematical tricks are not ideal. This program will be audited by somebody who is a mathematician who will want to be able to prove that the function does what it is supposed to do.
  3. Speed... I've got to compare a lot of numbers so the faster the better.
  4. I've got numpy, scipy and the standard-library. Anything else will be hard for me to get, especially for such a small part of the project.

解决方案

There is a function assert_approx_equal in numpy.testing (source here) which may be a good starting point.

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.

这篇关于用于确定两个数字四舍五入为十位十进制数时几乎相等的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆