测试浮点相等。 (FE_FLOATING_POINT_EQUALITY)
我在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))。 一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。 推荐的语言是“注意:此类具有与equals不一致的自然顺序。”
以及有关浮点平等的文档
此操作比较两个浮点值是否相等。 由于浮点计算可能涉及舍入,因此计算的浮点值和双精度值可能不准确。 对于必须精确的值,例如货币值,请考虑使用固定精度类型,例如BigDecimal。 对于不必精确的值,请考虑比较某些范围内的相等性,例如:if(Math.abs(x-y)<.0000001)。 请参阅Java语言规范,第4.2.4节。
我不明白。 有人可以帮忙吗?
问题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问题:强烈建议在x.compareTo(y)
返回零的任何地方, x.equals(y)
应为true
。 在您的代码中,您已经实现了compareTo
,但是您没有覆盖equals
,因此您inheritance了Object
的equals
实现,并且不满足上述条件。
为了解决这个问题,在类中重写equals
(也许是hashCode
),这样当x.compareTo(y)
返回0时, x.equals(y)
将返回true
。
对于浮点警告,您应该记住浮点数是一种不精确的类型。 给出的标准参考(也许值得一读)是:
每个计算机科学家应该知道的关于浮点运算的大卫戈德伯格。
因为浮点数不是精确值 – 即使它们在向上舍入到几位小数时看起来相同 – 它们可能会略有不同,并且无法匹配。
Comparable接口期望其实现者具有某种行为; 警告告诉你你没有遵守这一点,并提供建议的行动。
我不同意上面的答案。 等于和比较在浮点比较中引入epsilons是错误的地方。
浮点值可以通过equals和compareTo精确比较,只需使用“==”运算符即可。
如果您的应用程序使用由计算结果的浮点数,则需要将这些值与epsilon方法进行比较,它应该仅在需要此值的位置进行。 例如,在数学线交叉法中。
但不是等于和比较。
这个警告非常误导。 这意味着比较两个浮点数,其中一个是计算结果,可能会产生意外结果。 然而,通常这种浮动,比较,不是计算的结果,如
static final double INVALID_VALUE = -99.0; if (f == INVALID_VALUE)
其中f用INVALID_VALUE初始化,在java中总是能完美地工作。 但是,findbugs和sonarcube仍然会抱怨。
所以只需在findbugs中添加一个忽略filter,假设你有两个类MyPoint2D和Myrectangle2D