JavaでBigDecimal変数== 0かどうかを確認するにはどうすればよいですか?


202

私はJavaで次のコードを持っています。

BigDecimal price; // assigned elsewhere

if (price.compareTo(new BigDecimal("0.00")) == 0) {
    return true;
}

if条件を記述する最善の方法は何ですか?


12
BigDecimalの.equals()メソッドの使用を提案する多くの回答があります。ただし、このメソッドではスケールが考慮されるため、compareTo()を使用することと同じではありません。
GriffeyDog

回答:


472

compareTo(BigDecimal.ZERO)代わりに使用equals()

if (price.compareTo(BigDecimal.ZERO) == 0) // see below

BigDecimal定数と比較することで、すべての実行BigDecimal.ZEROを構築する必要がなくなりnew BigDecimal(0)ます。

参考までに、BigDecimal定数BigDecimal.ONEBigDecimal.TEN用意されています。


注意!

使用できない理由BigDecimal#equals()は、スケールが考慮されるためです。

new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!

そのため、純粋な数値比較には適していません。ただし、以下をBigDecimal.compareTo()比較するときはスケールを考慮しません。

new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true

BigDecimal.ZERO.compareTo(price)== 0
Jackkobec

97

または、signum()を使用することもできます。

if (price.signum() == 0) {
    return true;
}

21
多分それはより速いですが、compareTo(BigDecimal.ZERO)はより読みやすくなっています。
ElYeante 2014年

@ElYeante、いつでもこれをメソッドでラップすることができます。これは、より読みやすい名前を持つか、ビジネスロジックの一部を説明することもできます。そのような比較に関連して
WeGa

3
残念ながらsignum()はnullセーフではありませんが、compareToはBigDecimal.ZERO.compareTo()のように比較する場合、そのことに注意してください
WeGa

15
@WeGaそれは真実ではありません:BigDecimal.ZERO.compareTo(null)NPEをスローします
ACV

5
@ACV、ご用心ありがとうございます。ソースコードを見ると、compareTo()は実際にはnull以外の引数しか想定していません。
WeGa 2017

24

確認できる定数があります。

someBigDecimal.compareTo(BigDecimal.ZERO) == 0

3
「ヨーダ状態」の用語を盗む許可が要求されました。
SimplyPanda


Java BigDecimalの振る舞いはequalscompareToあなたが思うほどではありません。docs.oracle.com/javase/1.5.0/docs/api/java/math/...
nhahtdh

2
BigDecimalのcompareToは、nullを渡した場合でも例外をスローします。
ジョンジャン

5

私は通常以下を使用します:

if (selectPrice.compareTo(BigDecimal.ZERO) == 0) { ... }

5

あるいは、BigDecimalクラスのequalsメソッドとcompareToメソッドの動作が互いに一貫していないことについて言及する価値があると思います。

これは基本的に次のことを意味します。

BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO)==0); //true
System.out.println(someValue.equals(BigDecimal.ZERO)); //false

したがって、someValue変数のスケールには十分注意する必要があります。そうしないと、予期しない結果が発生します。


5

equals()はオブジェクトなので、組み込みのZEROインスタンスを使用する必要があります。

if(selectPrice.equals(BigDecimal.ZERO))

.equals()selectPriceが同じスケールであるのでない限り、考慮に規模をとる(0)として.ZERO、これは偽を返します。

方程式のスケールをそのままにするには:

if(selectPrice.compareTo(BigDecimal.ZERO) == 0)

特定の数学的な状況0.00 != 0について.equals()は、スケールを考慮に入れると想像するのはこのためです。0.00100分の1の精度を提供します0が、それほど正確ではありません。状況によっては、こだわりたいかもしれません.equals()


Java BigDecimalの振る舞いはequalscompareToあなたが思うほどではありません。docs.oracle.com/javase/1.5.0/docs/api/java/math/...
nhahtdh

ドキュメントにリンクするのではなく、どういう意味か説明してください。私が提案したことはOPで機能するはずです。
NominSim 2012

エドウィン・ダロルゾの答えは、実際にそれをかなりよく説明しています。equalsスケールを考慮に入れますが、ここでは必要ありません。
nhahtdh 2012

@nhahtdh実際にの代わりに使用するequals 必要がある状況もありますが、情報をありがとうございcompareTo()ます。OPは彼が使用している数学のタイプを指定していません。そのため、両方のオプションを指定することをお勧めします。
NominSim 2012

3

GriffeyDogは間違いなく正しいです。

コード:

BigDecimal myBigDecimal = new BigDecimal("00000000.000000");
System.out.println("bestPriceBigDecimal=" + myBigDecimal);
System.out.println("BigDecimal.valueOf(0.000000)=" + BigDecimal.valueOf(0.000000));
System.out.println(" equals=" + myBigDecimal.equals(BigDecimal.ZERO));
System.out.println("compare=" + (0 == myBigDecimal.compareTo(BigDecimal.ZERO)));

結果:

myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
 equals=false
compare=true

BigDecimal比較の利点は理解していますが、(==、<、>、<=、> =演算子のように)直感的な構成とは見なしません。頭の中に100万もの(大丈夫、7つのもの)を抱えている場合、認知負荷を軽減できるものは何でも良いことです。だから私はいくつかの便利な便利な関数を作りました:

public static boolean equalsZero(BigDecimal x) {
    return (0 == x.compareTo(BigDecimal.ZERO));
}
public static boolean equals(BigDecimal x, BigDecimal y) {
    return (0 == x.compareTo(y));
}
public static boolean lessThan(BigDecimal x, BigDecimal y) {
    return (-1 == x.compareTo(y));
}
public static boolean lessThanOrEquals(BigDecimal x, BigDecimal y) {
    return (x.compareTo(y) <= 0);
}
public static boolean greaterThan(BigDecimal x, BigDecimal y) {
    return (1 == x.compareTo(y));
}
public static boolean greaterThanOrEquals(BigDecimal x, BigDecimal y) {
    return (x.compareTo(y) >= 0);
}

それらを使用する方法は次のとおりです。

    System.out.println("Starting main Utils");
    BigDecimal bigDecimal0 = new BigDecimal(00000.00);
    BigDecimal bigDecimal2 = new BigDecimal(2);
    BigDecimal bigDecimal4 = new BigDecimal(4);  
    BigDecimal bigDecimal20 = new BigDecimal(2.000);
    System.out.println("Positive cases:");
    System.out.println("bigDecimal0=" + bigDecimal0 + " == zero is " + Utils.equalsZero(bigDecimal0));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <  bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThan(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThanOrEquals(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal4=" + bigDecimal4 + " >  bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThan(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal4=" + bigDecimal4 + " >= bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThanOrEquals(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal20=" + bigDecimal20 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal20));
    System.out.println("Negative cases:");
    System.out.println("bigDecimal2=" + bigDecimal2 + " == zero is " + Utils.equalsZero(bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal4=" + bigDecimal4 + " is " + Utils.equals(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal4=" + bigDecimal4 + " <  bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThan(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal4=" + bigDecimal4 + " <= bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThanOrEquals(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >  bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThan(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal4));

結果は次のようになります。

Positive cases:
bigDecimal0=0 == zero is true
bigDecimal2=2 <  bigDecimal4=4 is true
bigDecimal2=2 == bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal4=4 is true
bigDecimal4=4 >  bigDecimal2=2 is true
bigDecimal4=4 >= bigDecimal2=2 is true
bigDecimal2=2 >= bigDecimal20=2 is true
Negative cases:
bigDecimal2=2 == zero is false
bigDecimal2=2 == bigDecimal4=4 is false
bigDecimal4=4 <  bigDecimal2=2 is false
bigDecimal4=4 <= bigDecimal2=2 is false
bigDecimal2=2 >  bigDecimal4=4 is false
bigDecimal2=2 >= bigDecimal4=4 is false

1
それを正確に説明する複数の答えがあります。別の答えを追加する意味は何ですか?追加情報がある場合は、新しい回答を追加することをお勧めしますが、この投稿ではそうではありません。
トム

ポイントを取る。ただし、何かを学んでいるときは、たとえ似ていても、できるだけ多くの例を見たいと思います。あなたのために、トム、私が便利だと思ったライブラリを追加しました。あなたの走行距離は異なる場合があります。:-)
Tihamer、

0

ここで、kotlinの便利な拡張機能を共有したいだけです。

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0

-2
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));

1
このコードは質問に答えることがありますが、問題を解決する方法および/または理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。あなたが今尋ねている人だけでなく、将来の読者のための質問に答えていることを忘れないでください!回答を編集して説明を追加し、適用される制限と前提を示してください。また、この回答が他の回答よりも適切である理由について言及しても問題ありません。
Dev-iL 2017

-8

0表す静的定数があります

BigDecimal.ZERO.equals(selectPrice)

次の代わりにこれを行う必要があります。

selectPrice.equals(BigDecimal.ZERO)

ケースを避けるためでselectPriceあるがnull


3
Java BigDecimalの動作 equalscompareToあなたが思うほどではありません。docs.oracle.com/javase/1.5.0/docs/api/java/math/...
nhahtdh

したがって、2行目について... selectedPriceがnullの場合は、NullPointerExceptionをスローするだけです。
user3206236
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.