比较浮点数不等式(在Python中)
assert tlf.z >= tlb.z, (tlf.z,trf.z)
AssertionError: (0.5, 0.5)
如你所见,我遇到了精度问题。我该如何重新表述这个断言,以便它能通过接近的值(这个“容差”应该有多大呢?),然后如果右边的值确实小于左边的值,我该如何调整右边的值,使它们变得完全相等?
2 个回答
我觉得willm1给的答案不太对。
让我来解释一下。
下面这个表达式:
tlf.z >= tlb.z - EPSILON
其实可以理解为:
(tlf.z > tlb.z - EPSILON) 或者 (tlf.z == tlb.z - EPSILON)
如果tlf.z > tlb.z
这个条件成立,即使它们之间的差距小于EPSILON,tlf.z > tlb.z - EPSILON
也会成立。无论EPSILON的值是什么。正确的写法应该是:
tlf.z > tlb.z + EPSILON
至于第二个表达式tlf.z == tlb.z - EPSILON
,只有当tlf.z
和tlb.z
的差正好等于EPSILON
时,它才会被认为是对的,这并不是我们想要的。我们希望它们之间的差距小于EPSILON
:
abs(tlf.z - tlb.z) <= EPSILON
总结一下,tlf.z >= tlb.z - EPSILON
应该写成:
(tlf.z > tlb.z + EPSILON) || (abs(tlf.z - tlb.z) <= EPSILON)
更新:
我在看一些代码时,突然发现(tlf.z > tlb.z + EPSILON) || (abs(tlf.z - tlb.z) <= EPSILON)
其实和tlf.z >= tlb.z - EPSILON
是等价的。
当我们在寻找相似性时,abs(tlf.z - tlb.z) <= EPSILON
,我们希望tlb.z
在下面的灰色区域内:
当我们在寻找tlf.z > tlb.z + EPSILON
时:
所以,我们实际上是在寻找:
这和tlf.z + EPSILON >= tlb.z
是一样的(等价于tlf.z >= tlb.z - EPSILON
)。
所以,willm1其实是对的。抱歉 :)
试试这个:
EPSILON = 10 ** -12
assert tlf.z >= tlb.z - EPSILON, (tlf.z,trf.z)
tlf.z = max(tlf.z,tlb.z)
基本上,你需要定义一个容忍度,用来处理“大于或等于”的情况,并且要考虑到这个容忍度。
选择EPSILON的值其实是个难题。这取决于你错误的来源,以及在这个来源和比较之间进行了多少次计算。如果计算次数不多,选择一个小一点的EPSILON值可能比较合适。我建议你先试试这个例子,如果还有问题再进行调整。