Comparing and Using BigDecimals


BigDecimal

The BigDecimal class provides operations for arithmetic (add, subtract, multiply, divide), scale manipulation, rounding, comparison, hashing, and format conversion. The BigDecimal represents immutable, arbitrary-precision signed decimal numbers. This class shall be used in a necessity of high-precision calculation.


Comparing BigDecimal

The method compareTo should be used to compare BigDecimals:

import java.math.BigDecimal;
 
public class BigDecimalComparison {
    public static void main(String[] args) {
        BigDecimal valueA = new BigDecimal(7);
        BigDecimal valueB = new BigDecimal(0);
        BigDecimal valueC = new BigDecimal(15);
 
        System.out.println("Comparison with zero: " + valueA.compareTo(valueB)); // Greater than zero, returns 1
        System.out.println("Comparison with same value: " + valueA.compareTo(valueA)); // Equal to zero, returns 0
        System.out.println("Comparison with greater value: " + valueA.compareTo(valueC)); // Less than zero, returns -1
    }
}

Commonly you should not use the equals method since it considers two BigDecimals equal only if they are equal in value and also scale:

import java.math.BigDecimal;
 
public class BigDecimalEquality {
    public static void main(String[] args) {
        BigDecimal valueA = new BigDecimal(10);
        BigDecimal valueB = new BigDecimal(10.00);
        BigDecimal valueC = new BigDecimal(7);
 
        // Equal in value and scale, returns true
        System.out.println("Equals to same value: " + valueA.equals(valueB));
        // Equal in value but different scale, returns false 
        System.out.println("Equals to same value, different scale: " + valueA.equals(valueC)); 
    }
}
 

Using BigDecimal instead of float

Due to way that the float type is represented in computer memory, results of operations using this type can be inaccurate - some values are stored as approximations. Good examples of this are monetary calculations. If high precision is necessary, other types should be used. e.g. Java 7 provides BigDecimal.

import java.math.BigDecimal;
 
public class FloatBigDecimalTest {
    public static void main(String[] args) {
        float accountBalance = 50000.00f;
        System.out.println("Operations using float:");
        System.out.println("1000 operations for 3.50");
        for(int i = 0; i < 1000; i++){
            accountBalance -= 3.50f;
        }
        System.out.println(String.format("Account balance after float operations: %.2f", accountBalance));
 
        BigDecimal accountBalanceTwo = new BigDecimal("50000.00");
        System.out.println("Operations using BigDecimal:");
        System.out.println("1000 operations for 3.50");
        BigDecimal operation = new BigDecimal("3.50");
        for(int i = 0; i < 1000; i++){
            accountBalanceTwo = accountBalanceTwo.subtract(operation);
        }
        System.out.println(String.format("Account balance after BigDecimal operations: %.2f", accountBalanceTwo));
    }
}

Output of this program is:

Operations using float:
1000 operations for 3.50
Account balance after float operations: 1649.97
 
Operations using BigDecimal:
1000 operations for 3.50
Account balance after BigDecimal operations: 1649.97

For a starting balance of 10000.00, after 1000 operations for 1.99, we expect the balance to be 8010.00. Using the float type gives us an answer around 8009.77, which is unacceptably imprecise in the case of monetary calculations. Using BigDecimal gives us the proper result.

Basic Programs