我有一个 Vector 类,代表三维空间中的一个点。此向量有一个方法normalize(self, length = 1)
,可以向下/向上缩放向量为length == vec.normalize(length).length
。
由于浮点数不精确,此方法的单位测试有时失败。我的问题是,如何在正确实施方法时确保此测试不会失败?是否可以 不用 测试近似值?
其他信息:
def testNormalize(self):
vec = Vector(random.random(), random.random(), random.random())
self.assertEqual(vec.normalize(5).length, 5)
此 有时 会产生AssertionError: 4.999999999999999 != 5
或AssertionError: 5.000000000000001 != 5
。
注意:我知道浮点问题可能在Vector.length
属性或Vector.normalize()
中。
答案 0 :(得分:100)
使用assertAlmostEqual
,assertNotAlmostEqual
。
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
通过计算差值,舍入到给定的小数位数(默认值为7)并比较为零来测试第一个和第二个大致相等。
基本上没有。
无法绕过floating point issue,因此您要么“舍入”vec.normalize
给出的结果,要么接受几乎相等的结果(两者中的每一个都是近似值)。
答案 1 :(得分:3)
通过使用浮点值,您可以接受一个小的可能不精确。因此,您的测试应测试您的计算值是否落在可接受的范围内,例如:
theoreticalValue - epsilon < normalizedValue < theoreticalValue + epsilon
其中epsilon
是一个非常小的值,您可以将其定义为由于浮点不精确而导致的变化。
答案 2 :(得分:1)
我认为有一种可能性是将函数应用于测试所有输入,所有中间计算的结果和输出都可由float
精确表示的情况。
举例说明:
In [2]: import math
In [4]: def norm(x, y):
...: return math.sqrt(x*x + y*y)
...:
In [6]: norm(3, 4) == 5
Out[6]: True
不确定这是多么实用......
答案 3 :(得分:1)
通常,您不应声明浮点数的相等性。相反,请确保结果在某些范围内,例如:
self.assertTrue(abs(vec.normalize(5).length - 5) < 0.001)