簡體   English   中英

測試浮點相等。 (FE_FLOATING_POINT_EQUALITY)

[英]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 ,因此您繼承了Objectequals實現,並且不滿足上述條件。

為了解決這個問題,在類中重寫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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM