web-dev-qa-db-ja.com

JavaでBigDecimal変数== 0かどうかを調べる方法は?

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

BigDecimal price; // assigned elsewhere

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

If条件を書くための最善の方法は何ですか?

175
JoJo

compareTo(BigDecimal.ZERO) の代わりに equals() を使用してください。

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

BigDecimal 定数 BigDecimal.ZERO と比較すると、実行のたびにnew BigDecimal(0)を作成する必要がなくなります。

参考までに、BigDecimalには定数 BigDecimal.ONE および BigDecimal.TEN があります。


注意!

BigDecimal#equals() を使えないのは、scaleを考慮しているからです。

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
392
Bohemian

あるいは、 signum() を使用できます。

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

あなたがチェックできる定数があります:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0
23
pablochan

あるいは、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
Edwin Dalorzo

私は通常以下を使います。

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

それらはオブジェクトなのでequals()を使いたいと思うでしょう、そして組み込みのZEROインスタンスを利用します:

if(selectPrice.equals(BigDecimal.ZERO))

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

式からスケールを外すには:

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

0.00 != 0という数学的な状況では、.equals()がスケールを考慮に入れると想像するのはこのためです。 0.00は百分の一の場所に精度を与えますが、0はそれほど正確ではありません。状況によっては.equals()を使い続けたいと思うかもしれません。

4
NominSim

Kotlinの便利な拡張機能をここで共有したいです。

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

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比較の利点は理解できますが、直感的に理解できる構文ではありません(==、<、>、<=、> =演算子など)。あなたがあなたの頭の中に百万のもの(わかりました、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
0
Tihamer