[英]Test for floating point equality. (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
,因此您繼承了Object
的equals
實現,並且不滿足上述條件。
為了解決這個問題,在類中重寫equals
(也許是hashCode
),這樣當x.compareTo(y)
返回0時, x.equals(y)
將返回true
。
對於浮點警告,您應該記住浮點數是一種不精確的類型。 給出的標准參考(也許值得一讀)是:
每個計算機科學家應該知道的關於浮點運算的大衛戈德伯格。
因為浮點數不是精確值 - 即使它們在向上舍入到幾位小數時看起來相同 - 它們可能會略有不同,並且無法匹配。
Comparable接口期望其實現者具有某種行為; 警告告訴你你沒有遵守這一點,並提供建議的行動。
我不同意上面的答案。 Equals和compareTo是在浮點比較中引入epsilons的錯誤位置。
浮點值可以通過equals和compareTo精確比較,只需使用“==”運算符即可。
如果您的應用程序使用由計算結果的浮點數,需要將這些值與epsilon方法進行比較,它應該只在需要這個值的地方進行。 例如,在數學線交叉法中。
但不是等於和比較。
這個警告非常誤導。 這意味着比較兩個浮點數,其中一個是計算結果,可能會產生意外結果。 然而,通常這種浮動,比較,不是計算的結果,如
static final double INVALID_VALUE = -99.0;
if (f == INVALID_VALUE)
其中f用INVALID_VALUE初始化,在java中總是能完美地工作。 但是,findbugs和sonarcube仍然會抱怨。
所以只需在findbugs中添加一個忽略過濾器,假設你有兩個類MyPoint2D和Myrectangle2D
<Match>
<OR>
<Class name="~.*\.MyPoint2D" />
<Class name="~.*\.MyRectangle2D" />
</OR>
<Bug code="FE" />
<Justification author="My Name" />
<Justification
text="Floating point equals works (here)." />
</Match>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.