実際、可能な解決策を見つけました
_//returns true
new BigDecimal("5.50").doubleValue() == new BigDecimal("5.5").doubleValue()
_
もちろん、Math.abs (v1 - v2) < EPS
のようなもので比較をより堅牢にするために改善できますが、問題はこの手法が受け入れられるか、より良い解決策があるかということです。
Javaデザイナーがその方法でBigDecimalのequalsを実装することを決めた理由を誰かが知っていれば、読むのは面白いでしょう。
BigDecimalのjavadocから
等しい
public boolean equals(Object x)
この
BigDecimal
と指定されたObject
が等しいかどうかを比較します。compareTo
とは異なり、このメソッドは2つのBigDecimal
オブジェクトが等しいと見なします(値とスケールが等しい場合のみ)(したがって、2.0はそうではありません)この方法で比較すると2.00に等しい)。
単にcompareTo() == 0
を使用してください
_==
_を使用してdoubleを比較する 悪い考えのようです 一般的に。
比較する数値で同じものにsetScaleを呼び出すことができます。
_new BigDecimal ("5.50").setScale(2).equals(new BigDecimal("5.5").setScale (2))
_
スケールを2つのうち大きい方に設定する場所:
_BigDecimal a1 = new BigDecimal("5.051");
BigDecimal b1 = new BigDecimal("5.05");
// wow, this is awkward in Java
int maxScale = Collections.max(new ArrayList() {{ a1.scale(), b1.scale()}});
System.out.println(
a1.setScale(maxScale).equals(b1.setScale(maxScale))
? "are equal"
: "are different" );
_
ただし、compareTo() == 0
を使用するのが最善の答えです。上記の私のアプローチの数値のいずれかのスケールの増加は、compareMagnitudeメソッドのドキュメントで次のように述べられているときに言及されている「不必要なインフレ」である可能性があります。
_/**
* Version of compareTo that ignores sign.
*/
private int compareMagnitude(BigDecimal val) {
// Match scales, avoid unnecessary inflation
long ys = val.intCompact;
long xs = this.intCompact;
_
そしてもちろん、compareTo
は既に実装されているので、はるかに使いやすいです。
先行ゼロを無視して比較する最も簡単な式は、Java 1.5:
bd1.stripTrailingZeros().equals(bd2.stripTrailingZeros())