Java BigDecimal

Filed Under: Java

Java BigDecimal class is used to deal with financial data. BigDecimal is preferred while dealing with high-precision arithmetic or situations that require more granular control over rounding off calculations.

Java BigDecimal

BigDecimals are Immutable, arbitrary-precision signed decimal numbers. Java BigDecimal class is defined in java.math package. Here is the BigDecimal class hierarchy:

Java BigDecimal

Java BigDecimal also provides us convenient control over scale and precision. Before we explore BigDecimal class, we’ll briefly discuss precision and scale.

Java BigDecimal Precision and Scale

By Definition, precision indicates the length of arbitrary precision integer whereas scale means the number of digits to the right of the decimal point. For example if we have a number “100.25” then precision is 5 because we need five digits to write down this number and scale is 2.

We’ll look at some examples to get the clear idea about precision and scale.


9999/10000 = 0.9999, scale = 4 and precision = 4
1/1000 = 0.0001, scale = 4 and precision = 1
0.000, special case and precision = 1

We can set scale for any BigInteger with constructors as well as methods available in the API. For now, let’s see how it effects the number:


9999 with scale 4 = 0.9999
9999 with scale 1 = 999.9 
9999 with scale -1 = 99990

We can clearly see that number gets multiplied by 10^-scale.

Java BigDecimal Constructors

There are several ways to create BigDecimal objects in Java. We’ll explore the constructors with code examples.

  1. BigDecimal(BigInteger val): It takes BigInteger as an argument and creates a BigDecimal Object out of it.
    
    BigInteger bigInt = new BigInteger("233233233233");
    BigDecimal bigDecimal = new BigDecimal(bigInt); 
    

    Similarly, there are constructors available in the class which accept int, double, long, char[] as well as String as an argument to create BigDecimal object:

    
    BigDecimal bigDecimal = new BigDecimal(5.0);
    
  2. BigDecimal(BigInteger unscaledVal, int scale): We can also provide scale along with the value while creating the object.

    
    BigInteger bigInt = new BigInteger("233233233233");
    int scale = 2;
    BigDecimal bigDecimal = new BigDecimal(bigInt, scale);
    System.out.println(bigDecimal);
    

    Output:

    
    2332332332.33
    
  3. BigDecimal(BigInteger val, MathContext mc): It also gives us control to provide MathContext instance while creating the object.
    Basically, it provides precision matching IEEE 754R Format. Following are the possible values for java.math.MathContext:

    1. MathContext.DECIMAL128 ? to provide precision of 34 digits.
    2. MathContext.DECIMAL64 – to provide precision of 16 digits.
    3. MathContext.DECIMAL32 ? to provide precision of 7 digits.
    4. MathContext.UNLIMITED ? to provide unlimited precision.

    Let’s look at the code:

    
    BigInteger bigInt = new BigInteger("233233233233");
    BigDecimal bigDecimal = new BigDecimal(bigInt, MathContext.DECIMAL32);
    

    Ofcourse, it also provides similar constructors for int, long, double, char[] as well as String.

  4. BigDecimal(BigInteger unscaledVal, int scale, MathContext mc): we can provide both scale and precision at the time of construction of an object.

    
    BigInteger bigInt = new BigInteger("233233233233");
    int scale = 2;
    BigDecimal bigDecimal = new BigDecimal(bigInt, scale,MathContext.DECIMAL32);
    

Java BigDecimal Methods

Java BigDecimal class provides us with several method to perform arithmatic operations, scale manipulation, rounding, comparision and formatting.

Note that we can’t use operators such as +, – with it as they are not overloaded for the class. Instead, it provides respective methods to achieve the results.
Let’s look at the methods provided in the BigDecimal API with examples:

  1. BigDecimal add(BigDecimal bigDecimal2): Returns a BigDecimal whose value is addition of this and bigDecimal2.
    
    BigInteger bigInt = new BigInteger("233233233233");
    int scale = 2;
    BigDecimal bigDecimal = new BigDecimal(bigInt, scale);
    BigDecimal bigDecimal2 = new BigDecimal(55662.3);
    System.out.println(bigDecimal.add(bigDecimal2));
    
    
    2332387994.630000000002910383045673370361328125
    

    As you can see, returned object from add() method has scale which is max(this.scale, bigDecimal2). In our case, bigDecimal2 is created with the double and takes the scale value from it.
    There is also an overloaded add(BigDecimal bigDecimal2, MathContext mc) method which takes precision as argument and returns a BigDecimal object with rounding according to context settings.

  2. BigDecimal subtract(BigDecimal bigDecimal2): Returns a BigDecimal whose value is subtraction of this and bigDecimal2.
    Similar to add() method, it also has privision to provide MathContext instance.

    
    System.out.println(bigDecimal.subtract(bigDecimal2));
    2332276670.029999999997089616954326629638671875
    
  3. BigDecimal setScale(int newScale, RoundingMode roundingMode): A very Convinient and powerful method which allows us to set scale as well as rounding mode of the object. We already discussed scale. Let’s briefly discuss rounding mode and its possible values:
    An enum RoundingMode provides following possible rounding:

    1. UP: to round away from zero
    2. CEILING: to round towards positive infinity
    3. DOWN: to round towards zero
    4. FLOOR: to round towards negative infinity
    5. HALF_DOWN: to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round down
    6. HALF_EVEN: to round towards the “nearest neighbor” unless both neighbors are equidistant, in which case, round towards the even neighbor
    7. HALF_UP: to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round up
    8. UNNECESSARY: to assert that the requested operation has an exact result, hence no rounding is necessary
    
    BigDecimal bigDecimal = new BigDecimal("23323323.3533");
    System.out.println(bigDecimal);
    System.out.println("CEILING: "+bigDecimal.setScale(2,RoundingMode.CEILING));
    System.out.println("DOWN: "+bigDecimal.setScale(2,RoundingMode.DOWN));
    System.out.println("FLOOR: "+bigDecimal.setScale(2,RoundingMode.FLOOR));
    

    Output:

    
    23323323.3533
    CEILING: 23323323.36
    DOWN: 23323323.35
    FLOOR: 23323323.35
    
  4. BigInteger unscaledValue(): We can also get unscaled values at any point of time.
    For Example, following code:

    
    BigDecimal bigDecimal = new BigDecimal("23323323.3533");
    System.out.println(bigDecimal);
    System.out.println(bigDecimal.unscaledValue());
    

    will get us:

    
    23323323.3533
    233233233533
    

    there is also scale() method which returns scale of the BigDecimal object

  5. BigDecimal divide(BigDecimal divisor, int roundingMode): Computes division of this and divisor and returns the output with provided roundingMode.
  6. BigDecimal divide(BigDecimal divisor, int scale, int roundingMode): Computes division of this and divisor and returns the output with provided roundingMode and scale.
  7. BigDecimal multiply(BigDecimal multiplicand): Computes multiplication of this and multiplicand and returns the output.
  8. BigDecimal pow(int n): Returns a BigDecimal whose value is (this^n), The power is computed exactly, to unlimited precision.

Note that for each operator method, there is an overloaded method which accepts MathContext object and returns the output with respective precision.

Java BigDecimal Example

Now, let’s have a look at an example to check out above java BigDecimal methods:


BigDecimal bigDecimal = new BigDecimal("2255223");
BigDecimal bigDecimal2 = new BigDecimal("55662.3");
System.out.println("Division by specifying rounding mode: " + bigDecimal.divide(bigDecimal2, RoundingMode.CEILING));
System.out.println("Division by specifying scale and rounding mode: "+ bigDecimal.divide(bigDecimal2, 2, RoundingMode.CEILING));
System.out.println("Multiplication: "+bigDecimal.multiply(bigDecimal2));
System.out.println("Power: "+bigDecimal.pow(2));

Output:


Division by specifying rounding mode: 41
Division by specifying scale and rounding mode: 40.52
Multiplication: 125530899192.9
Power: 5086030779729

There are many methods provided in the BigDecimal class for various operators such as min(), max(). Also, it provides with methods such as intValue(), doubleValue(), longValue() to get output in required format.

Java BigDecimal Formatting

We can use the api along with java.text.NumberFormat to apply desired formatting to the big numbers. For instance, let’s say we want to print the amount in USD:


BigDecimal bigDecimal = new BigDecimal("225522333333");
System.out.println("Unformatted: " + bigDecimal.toString());
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US);
double money = bigDecimal.doubleValue();
String s = n.format(money);
System.out.println("Formatted: "+s);

Output:


Unformatted: 225522333333
Formatted: $225,522,333,333.00

Java BigDecimal compareTo

Java BigDecimal class implements Comparable interface and we should use it’s compareTo method to compare two BigDecimal objects.

Note that two BigDecimal objects that are equal in value but have a different scale (like 10.0 and 10.00) are considered equal by compareTo method.


BigDecimal bd1 = new BigDecimal("100");
BigDecimal bd2 = new BigDecimal("100.00");
BigDecimal bd3 = new BigDecimal("50");
BigDecimal bd4 = new BigDecimal("200");

System.out.println("100 compareTo 100.00 = "+bd1.compareTo(bd2));
System.out.println("100 compareTo 50 = "+bd1.compareTo(bd3));
System.out.println("100 compareTo 200 = "+bd1.compareTo(bd4));

Output of above BigDecimal compareTo example code is:


100 compareTo 100.00 = 0
100 compareTo 50 = 1
100 compareTo 200 = -1

Java BigDecimal toString

Java BigDecimal toString method behaves differently based on the scale value. If the scale is 6 or more, then it prints in exponential notation. Below are some pseudo code to show the BigDecimal value with scale and the String representation returned by toString method.


 [456,0]      "456"
 [-456,0]     "-456"
 [456,-1]     "4.56E+3"
 [456,-3]     "4.56E+5"
 [456,1]      "45.6"
 [456,5]      "0.00456"
 [456,10]     "4.56E-8"
 [-456,12]    "-4.56E-10"

Here is a simple java example for BigDecimal toString example.


BigDecimal bd1 = new BigDecimal(new BigInteger("10"),10);
System.out.println("BigDecimal(10) with Scale 10 toString = "+bd1);

bd1 = new BigDecimal(new BigInteger("10"),4);
System.out.println("BigDecimal(10) with Scale 4 toString = "+bd1);

Output produced by above BigDecimal toString example code is:


BigDecimal(10) with Scale 10 toString = 1.0E-9
BigDecimal(10) with Scale 4 toString = 0.0010

That’s all for Java BigDecimal class.

Reference: API Doc

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages