alv*_*vas 17 python testing floating-point precision unit-testing
假设我正在为一个返回浮点数的函数编写一个单元测试,我可以按照我的机器完全精确地完成它:
>>> import unittest
>>> def div(x,y): return x/float(y)
...
>>>
>>> class Testdiv(unittest.TestCase):
... def testdiv(self):
... assert div(1,9) == 0.1111111111111111
...
>>> unittest.main()
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
OS /发行版/机器上相同的完全浮点精度是否相同?
我可以尝试完成并进行单元测试:
>>> class Testdiv(unittest.TestCase):
... def testdiv(self):
... assert round(div(1,9),4) == 0.1111
...
>>>
Run Code Online (Sandbox Code Playgroud)
我也可以做一个断言,log(output)
但为了保持固定小数精度,我仍然需要进行舍入或截断.
但是,还有什么其他方式可以解决浮点输出的单元测试?
vau*_*tah 28
float
Python 的精度取决于底层的C表示.从教程/浮点算术:问题和限制,15.1:
今天(2000年11月)几乎所有机器都使用IEEE-754浮点运算,几乎所有平台都将Python浮点数映射到IEEE-754"双精度".
至于测试,更好的想法是使用现有功能,例如TestCase.assertAmostEqual
:
assertAlmostEqual(first,second,places = 7,msg = None,delta = None)
测试第一和第二近似(或不近似)通过计算差,四舍五入到小数点的给定数目相等的地方(默认7),并与零进行比较.如果提供delta而不是地点,则第一个和第二个之间的差值必须小于或等于(或大于)delta.
例:
import unittest
def div(x, y): return x / float(y)
class Testdiv(unittest.TestCase):
def testdiv(self):
self.assertAlmostEqual(div(1, 9), 0.1111111111111111)
self.assertAlmostEqual(div(1, 9), 0.1111, places=4)
unittest.main() # OK
Run Code Online (Sandbox Code Playgroud)
如果你更喜欢坚持assert
语句,你可以使用math.isclose
(Python 3.5+):
import unittest, math
def div(x, y): return x / float(y)
class Testdiv(unittest.TestCase):
def testdiv(self):
assert math.isclose(div(1, 9), 0.1111111111111111)
unittest.main() # OK
Run Code Online (Sandbox Code Playgroud)
默认的相对容差math.close
是1e-09,"这确保了两个值在大约9个十进制数字内相同." .有关详细信息,math.close
请参阅PEP 485.
该unittest.TestCase
班有比较彩车具体方法:assertAlmostEqual
和assertNotAlmostEqual
.引用文档:
assertAlmostEqual(first,second,places = 7,msg = None,delta = None) assertNotAlmostEqual(first,second,places = 7,msg = None,delta = None)
测试第一和第二近似(或不近似)通过计算差,四舍五入到小数点的给定数目相等的地方(默认7),并与零进行比较.请注意,这些方法将值四舍五入到给定的小数位数(即
round()
函数),而不是有效数字.如果提供delta而不是地点,则第一个和第二个之间的差值 必须小于或等于(或大于)delta.
因此,您可以像这样测试函数:
self.assertAlmostEqual(div(1, 9), 0.1111111111111111) # round(a-b, 7) == 0
self.assertAlmostEqual(div(1, 9), 0.1111, 4) # round(a-b, 4) == 0
Run Code Online (Sandbox Code Playgroud)
使用这些TestCase.assert*
方法优于裸assert
语句,因为后者可以在某些情况下进行优化.此外,由这些方法产生的测试失败消息通常提供更多信息.
归档时间: |
|
查看次数: |
8760 次 |
最近记录: |