173

I have a domain class with unitPrice set as BigDecimal data type. Now I am trying to create a method to compare price but it seems like I can't have comparison operators in BigDecimal data type. Do I have to change data type or is there other way around?

AlexElin
  • 1,044
  • 14
  • 23
user3127109
  • 3,421
  • 8
  • 24
  • 33
  • since `BigDecimal` is an `Object`, no this doesn´t work. But you could simply subtract one from each other and check if the resulting value is `<0`, `==0` or `>0`. Otherwise you could go the standard way with the provided methods from [BigDecimal](http://stackoverflow.com/questions/6787142/bigdecimal-equals-versus-compareto) – SomeJavaGuy Jan 08 '16 at 12:56
  • 3
    That why there is a `compareTo` method which returns -1, 0 or 1. Which is basically the [`Comparable`](https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html). – M. Deinum Jan 08 '16 at 12:57
  • https://github.com/mortezaadi/bigdecimal-utils – Morteza Adi Sep 30 '18 at 11:50

11 Answers11

249

To be short:

firstBigDecimal.compareTo(secondBigDecimal) < 0 // "<"
firstBigDecimal.compareTo(secondBigDecimal) > 0 // ">"    
firstBigDecimal.compareTo(secondBigDecimal) == 0 // "=="  
firstBigDecimal.compareTo(secondBigDecimal) >= 0 // ">="    
torina
  • 3,825
  • 2
  • 26
  • 31
153

Every object of the Class BigDecimal has a method compareTo you can use to compare it to another BigDecimal. The result of compareTo is then compared > 0, == 0 or < 0 depending on what you need. Read the documentation and you will find out.

The operators ==, <, > and so on can only be used on primitive data types like int, long, double or their wrapper classes like Integerand Double.

From the documentation of compareTo:

Compares this BigDecimal with the specified BigDecimal.

Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators.

Returns: -1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.

assylias
  • 321,522
  • 82
  • 660
  • 783
Simulant
  • 19,190
  • 8
  • 63
  • 98
30

Use the compareTo method of BigDecimal :

public int compareTo(BigDecimal val) Compares this BigDecimal with the specified BigDecimal.

Returns:
-1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.
Valentin Michalak
  • 2,089
  • 1
  • 14
  • 27
Arnaud
  • 17,229
  • 3
  • 31
  • 44
25

Here is an example for all six boolean comparison operators (<, ==, >, >=, !=, <=):

BigDecimal big10 = new BigDecimal(10);
BigDecimal big20 = new BigDecimal(20);

System.out.println(big10.compareTo(big20) < -1);  // false
System.out.println(big10.compareTo(big20) <= -1); // true
System.out.println(big10.compareTo(big20) == -1); // true
System.out.println(big10.compareTo(big20) >= -1); // true
System.out.println(big10.compareTo(big20) > -1);  // false
System.out.println(big10.compareTo(big20) != -1); // false

System.out.println(big10.compareTo(big20) < 0);   // true
System.out.println(big10.compareTo(big20) <= 0);  // true
System.out.println(big10.compareTo(big20) == 0);  // false
System.out.println(big10.compareTo(big20) >= 0);  // false
System.out.println(big10.compareTo(big20) > 0);   // false
System.out.println(big10.compareTo(big20) != 0);  // true

System.out.println(big10.compareTo(big20) < 1);   // true
System.out.println(big10.compareTo(big20) <= 1);  // true
System.out.println(big10.compareTo(big20) == 1);  // false
System.out.println(big10.compareTo(big20) >= 1);  // false
System.out.println(big10.compareTo(big20) > 1);   // false
System.out.println(big10.compareTo(big20) != 1);  // true
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
ognjenkl
  • 1,407
  • 15
  • 11
18

You can use method named compareTo, x.compareTo(y). It will return 0 if x and y are equal, 1 if x is greater than y and -1 if x is smaller than y

Agung Setiawan
  • 1,134
  • 3
  • 13
  • 32
9

Alternatively, if you're already using commons-lang3 (version 3.10 and up), you can leverage their ComparableUtils API like so:

import static org.apache.commons.lang3.compare.ComparableUtils.is;

var areEqual = is(first).equalTo(second);
var isGreater = is(first).greaterThan(second);
var isLess = is(first).lessThan(second);
var isBetween = is(first).between(second, third);
// etc.

Nowadays, most large projects include commons-lang3 as a dependency, anyway.

Priidu Neemre
  • 2,813
  • 2
  • 39
  • 40
8

Discussion

This thread has plenty of answers stating that the BigDecimal.compareTo(BigDecimal) method is the one to use to compare BigDecimal instances. I just wanted to add for anyone not experienced with using the BigDecimal.compareTo(BigDecimal) method: Be careful with how you create your BigDecimal instances. For example:

  • new BigDecimal(0.8) will create a BigDecimal instance with a value which is not exactly 0.8 and which has a scale of 50+,
  • new BigDecimal("0.8") will create a BigDecimal instance with a value which is exactly 0.8 and which has a scale of 1.

These two BigDecimal instances are unequal according to the BigDecimal.compareTo(BigDecimal) method because their values are unequal when the scale is not limited to a few decimal places.

Summary

Firstly, be careful to create your BigDecimal instances with the BigDecimal(String val) constructor or the BigDecimal.valueOf(double val) method rather than the BigDecimal(double val) constructor. Secondly, note that you can limit the scale of BigDecimal instances prior to comparing them by means of the BigDecimal.setScale(int newScale, RoundingMode roundingMode) method.

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
6

BigDecimal isn't a primitive, so you cannot use the <, > operators. However, since it's a Comparable, you can use the compareTo(BigDecimal) to the same effect. E.g.:

public class Domain {
    private BigDecimal unitPrice;

    public boolean isCheaperThan(BigDecimal other) {
        return unitPirce.compareTo(other.unitPrice) < 0;
    }

    // etc...
}
Anatoly Shamov
  • 2,608
  • 1
  • 17
  • 27
Mureinik
  • 297,002
  • 52
  • 306
  • 350
3

You can follow this utility static method and Operator enum for comparing the two numbers:

public static boolean check(BigDecimal firstNum, Operator operator, BigDecimal secondNum) {
    switch (operator) {
        case EQUALS:
            return firstNum.compareTo(secondNum) == 0;
        case LESS_THAN:
            return firstNum.compareTo(secondNum) < 0;
        case LESS_THAN_OR_EQUALS:
            return firstNum.compareTo(secondNum) <= 0;
        case GREATER_THAN:
            return firstNum.compareTo(secondNum) > 0;
        case GREATER_THAN_OR_EQUALS:
            return firstNum.compareTo(secondNum) >= 0;
    }

    throw new IllegalArgumentException("Will never reach here");
}

public enum Operator {
    LESS_THAN, LESS_THAN_OR_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUALS, EQUALS
}
Mehdi
  • 3,795
  • 3
  • 36
  • 65
0

Using com.ibm.etools.marshall.util.BigDecimalRange util class of IBM one can compare if BigDecimal in range.

boolean isCalculatedSumInRange = BigDecimalRange.isInRange(low, high, calculatedSum);
Alexey
  • 39
  • 5
0

Below is an example to compare two BigDecimal values.

public class BigDecimalDemo {

   public static void main(String[] args) {

      // create 2 BigDecimal objects
      BigDecimal bg1, bg2;

      bg1 = new BigDecimal("10");
      bg2 = new BigDecimal("20");

      //create int object
      int res;

      res = bg1.compareTo(bg2); // compare bg1 with bg2

      String str1 = "Both values are equal ";
      String str2 = "First Value is greater ";
      String str3 = "Second value is greater";

      if( res == 0 )
         System.out.println( str1 );
      else if( res == 1 )
         System.out.println( str2 );
      else if( res == -1 )
         System.out.println( str3 );
   }
}
David Kariuki
  • 1,522
  • 1
  • 15
  • 30