22

ANT スクリプトで findbugs を使用していますが、2 つのエラーを修正する方法がわかりません。ドキュメントを読みましたが、理解できません。ここに私のエラーとそれに伴うコードがあります:

エラー 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 と矛盾する自然な順序付けがあります。」

また、浮動小数点の等価性に関するドキュメント

この操作は、2 つの浮動小数点値が等しいかどうかを比較します。浮動小数点の計算には丸めが含まれる場合があるため、計算された float 値と double 値は正確ではない場合があります。金額など、正確でなければならない値については、BigDecimal などの固定精度型の使用を検討してください。正確である必要のない値については、たとえば if ( Math.abs(x - y) < .0000001 ) のように、ある範囲内で等しいかどうかを比較することを検討してください。Java 言語仕様のセクション 4.2.4 を参照してください。

わからないけど。誰でも助けてもらえますか?

4

3 に答える 3

19

問題 1:

FE_FLOATING_POINT_EQUALITY の問題については、2 つの float 値を演算子で直接比較しないでください。==わずかな丸め誤差が原因で、条件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)0 を返す場所は常に にすることを強くお勧めしx.equals(y)ますtrue。あなたのコードでは を実装compareToしましたが、オーバーライドしていないため、 fromequalsの実装を継承しており、上記の条件が満たされていません。equalsObject

これを修正するには、クラスでequals(およびおそらく を) オーバーライドして、 0 が返されたときに が返されるようにします。hashCodex.compareTo(y)x.equals(y)true

于 2010-10-03T18:12:50.760 に答える
6

浮動小数点の警告については、float は不正確な型であることに注意してください。これについてよく与えられる標準的なリファレンス (おそらく一度読む価値があります) は次のとおりです。

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと(David Goldberg 著)。

浮動小数点数は正確な値ではないため、小数点以下を切り上げたときに同じように見えても、わずかに異なる可能性があり、一致しません。

Comparable インターフェースは、その実装者による特定の動作を期待しています。警告は、あなたがそれに準拠していないことを伝え、推奨されるアクションを提供しています。

于 2010-09-30T17:28:23.567 に答える
2

上記の回答には同意しません。Equals と compareTo は、浮動小数点比較でイプシロンを導入するのに不適切な場所です。

浮動小数点値は、「==」演算子を使用するだけで、equals と compareTo によって正確に比較できます。アプリケーションが計算
の結果である float を使用し、これらの値をイプシロン アプローチと比較する必要がある場合は、これが必要な場所でのみ実行する必要があります。たとえば、数学的線交差法で。 しかし、equals と compareTo ではありません。

この警告は非常に誤解を招くものです。これは、少なくとも 1 つが計算の結果である 2 つの float を比較すると、予期しない結果が生じる可能性があることを意味します。ただし、多くの場合、そのようなフロートは、比較すると、次のような計算の結果ではありません。

static final double INVALID_VALUE = -99.0;
if (f == INVALID_VALUE)

ここで、f は INVALID_VALUE で初期化され、Java では常に完全に機能します。しかし、findbugs と sonarcube はまだ文句を言います。

したがって、MyPoint2D と Myrectangle2D の 2 つのクラスがあると仮定して、findbugs に無視フィルタを追加するだけです。

<Match>
        <OR>
            <Class name="~.*\.MyPoint2D" />
            <Class name="~.*\.MyRectangle2D" />
        </OR>
        <Bug code="FE" />
        <Justification author="My Name" />
        <Justification
            text="Floating point equals works (here)." />
    </Match>
于 2015-04-21T13:53:21.863 に答える