比较浮点数不等式(在Python中)

2 投票
2 回答
3229 浏览
提问于 2025-04-16 14:51
assert tlf.z >= tlb.z, (tlf.z,trf.z)
AssertionError: (0.5, 0.5)

如你所见,我遇到了精度问题。我该如何重新表述这个断言,以便它能通过接近的值(这个“容差”应该有多大呢?),然后如果右边的值确实小于左边的值,我该如何调整右边的值,使它们变得完全相等?

2 个回答

3

我觉得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.ztlb.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其实是对的。抱歉 :)

3

试试这个:

EPSILON = 10 ** -12
assert tlf.z >= tlb.z - EPSILON, (tlf.z,trf.z)
tlf.z = max(tlf.z,tlb.z)

基本上,你需要定义一个容忍度,用来处理“大于或等于”的情况,并且要考虑到这个容忍度。

选择EPSILON的值其实是个难题。这取决于你错误的来源,以及在这个来源和比较之间进行了多少次计算。如果计算次数不多,选择一个小一点的EPSILON值可能比较合适。我建议你先试试这个例子,如果还有问题再进行调整。

撰写回答