测试浮点相等性。(FE_FLOATING_POINT_EQUALITY)

2022-09-02 01:32:30

我在ANT脚本中使用了findbugs,但我不知道如何修复我的两个错误。我已经阅读了文档,但不明白。以下是我的错误和随之而来的代码:

错误 1:测试浮点相等性。(FE_FLOATING_POINT_EQUALITY)

private boolean equals(final Quantity other) {
    return this.mAmount == convertedAmount(other);
}

错误 2:EQ_COMPARETO_USE_OBJECT_EQUALS

public final int compareTo(final Object other) {
    return this.description().compareTo(((Decision) other).description());
}

我已阅读了 ComparesTo 问题的文档,其中指出

强烈建议,但不是严格要求 (x.compareTo(y)==0) == (x.equals(y))。一般来说,任何实现Able接口并违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:这个类有一个与equals不一致的自然排序。

以及关于浮点相等性的文档

此操作将比较两个浮点值以实现相等。由于浮点计算可能涉及舍入,因此计算的浮点数和双精度值可能不准确。对于必须精确的值(如货币值),请考虑使用固定精度类型(如 BigDecimal)。对于不需要精确的值,请考虑比较某个范围内的相等性,例如:如果( Math.abs(x - y) < .0000001 )。请参阅 Java 语言规范,第 4.2.4 节。

我不明白。任何人都可以帮忙吗?


答案 1

问题 1:

对于FE_FLOATING_POINT_EQUALITY问题,不应直接与运算符比较两个浮点值,因为由于微小的舍入错误,即使条件不成立,这些值对于您的应用程序来说也可能在语义上“相等”。==value1 == value2

要解决此问题,请按如下方式修改代码:

private boolean equals(final Quantity other) {
    return (Math.abs(this.mAmount - convertedAmount(other)) < EPSILON);
}

其中,EPSILON 是您应该在代码中定义的常量,表示您的应用程序可接受的微小差异,例如 .0000001。

问题 2:

对于EQ_COMPARETO_USE_OBJECT_EQUALS问题:强烈建议返回零的位置应为 。在你的代码中,你已经实现了,但你还没有重写,所以你继承了 from 的实现,并且不满足上述条件。x.compareTo(y)x.equals(y)truecompareToequalsequalsObject

为了解决这个问题,在你的类中重写(也许),这样当返回0时,那么将返回。equalshashCodex.compareTo(y)x.equals(y)true


答案 2

对于浮点警告,应记住浮点数是一种不精确的类型。为此经常给出的标准参考(也许值得一读一次)是:

每个计算机科学家都应该知道的关于David Goldberg的浮点算术

由于浮点数不是精确值 - 即使它们在向上舍入到几个小数时看起来相同 - 它们也可能非常小,并且无法匹配。

可比较接口期望其实现者具有某种行为;警告告诉您您没有遵守这一点,并提供建议的行动。


推荐