如何对浮点输出执行单元测试?-蟒蛇


问题内容

假设我正在为返回浮点数的函数编写单元测试,我可以按照我的机器的精度来做到这一点:

>>> 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

在OS /发行版/机器上,相同的全浮点精度是否相同?

我可以尝试四舍五入并做这样的单元测试:

>>> class Testdiv(unittest.TestCase):
...     def testdiv(self):
...             assert round(div(1,9),4) == 0.1111
... 
>>>

我也可以使用断言,log(output)但要保持固定的十进制精度,我仍然需要四舍五入。

但是,Python应该以什么其他方式用Python处理浮点输出的单元测试?


问题答案:

floatPython中的精度取决于基础C表示形式。从
教程/浮点算法:问题和局限性,15.1

如今(2000年11月),几乎所有机器都使用IEEE-754浮点算法,几乎所有平台都将Python浮点数映射到IEEE-754“双精度”。


至于测试,一个更好的主意是使用现有功能,例如TestCase.assertAlmostEqual

assertAlmostEqual(第一,第二,地方= 7,msg =无,增量=无)

测试 第一第二 近似(或不近似)通过计算差,舍入到给定数目的小数等于 地方 (默认7),并与零进行比较。如果提供了 delta
而不是 place,第一第二个 之间的差必须小于或等于(或大于) 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

如果您喜欢坚持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

默认的相对公差math.close为1e-09, “这确保两个值在大约9个十进制数字内相同”。
。有关更多信息,math.close请参见PEP 485