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 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.
1 2 3 4 5 |
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:
1 2 3 4 5 |
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.
BigDecimal(BigInteger val)
: It takes BigInteger as an argument and creates a BigDecimal Object out of it.
1234BigInteger 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:
123BigDecimal bigDecimal = new BigDecimal(5.0);BigDecimal(BigInteger unscaledVal, int scale)
: We can also provide scale along with the value while creating the object.
123456BigInteger bigInt = new BigInteger("233233233233");int scale = 2;BigDecimal bigDecimal = new BigDecimal(bigInt, scale);System.out.println(bigDecimal);
Output:
123<span style="color: #008000;"><strong><code>2332332332.33</code></strong></span>BigDecimal(BigInteger val, MathContext mc)
: It also gives us control to provideMathContext
instance while creating the object.
Basically, it provides precision matching IEEE 754R Format. Following are the possible values forjava.math.MathContext
:
- MathContext.DECIMAL128 ? to provide precision of 34 digits.
- MathContext.DECIMAL64 – to provide precision of 16 digits.
- MathContext.DECIMAL32 ? to provide precision of 7 digits.
- MathContext.UNLIMITED ? to provide unlimited precision.
Let’s look at the code:
1 2 3 4 |
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.
BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)
: we can provide both scale and precision at the time of construction of an object.
12345BigInteger 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:
BigDecimal add(BigDecimal bigDecimal2)
: Returns a BigDecimal whose value is addition ofthis
andbigDecimal2
.
1234567BigInteger 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));
1232332387994.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 overloadedadd(BigDecimal bigDecimal2, MathContext mc)
method which takes precision as argument and returns a BigDecimal object with rounding according to context settings.BigDecimal subtract(BigDecimal bigDecimal2)
: Returns a BigDecimal whose value is subtraction ofthis
andbigDecimal2
.
Similar to add() method, it also has privision to provide MathContext instance.
1 2 3 4 |
System.out.println(bigDecimal.subtract(bigDecimal2)); 2332276670.029999999997089616954326629638671875 |
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:- UP: to round away from zero
- CEILING: to round towards positive infinity
- DOWN: to round towards zero
- FLOOR: to round towards negative infinity
- HALF_DOWN: to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round down
- HALF_EVEN: to round towards the “nearest neighbor” unless both neighbors are equidistant, in which case, round towards the even neighbor
- HALF_UP: to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round up
- UNNECESSARY: to assert that the requested operation has an exact result, hence no rounding is necessary
1234567BigDecimal 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:
123456<span style="color: #008000;"><strong><code>23323323.3533CEILING: 23323323.36DOWN: 23323323.35FLOOR: 23323323.35</code></strong></span>BigInteger unscaledValue()
: We can also get unscaled values at any point of time.
For Example, following code:12345BigDecimal bigDecimal = new BigDecimal("23323323.3533");System.out.println(bigDecimal);System.out.println(bigDecimal.unscaledValue());will get us:
123423323323.3533233233233533there is also
scale()
method which returns scale of theBigDecimal
objectBigDecimal divide(BigDecimal divisor, int roundingMode)
: Computes division ofthis
anddivisor
and returns the output with provided roundingMode.BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
: Computes division ofthis
anddivisor
and returns the output with provided roundingMode and scale.BigDecimal multiply(BigDecimal multiplicand)
: Computes multiplication ofthis
andmultiplicand
and returns the output.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:
1 2 3 4 5 6 7 8 |
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:
1 2 3 4 5 6 |
<span style="color: #008000;"><strong><code> Division by specifying rounding mode: 41 Division by specifying scale and rounding mode: 40.52 Multiplication: 125530899192.9 Power: 5086030779729 </code></strong></span> |
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:
1 2 3 4 5 6 7 8 |
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:
1 2 3 4 |
<span style="color: #008000;"><strong><code> Unformatted: 225522333333 Formatted: $225,522,333,333.00 </code></strong></span> |
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.
1 2 3 4 5 6 7 8 9 |
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:
1 2 3 4 5 |
<span style="color: #003300;"><strong><code> 100 compareTo 100.00 = 0 100 compareTo 50 = 1 100 compareTo 200 = -1 </code></strong></span> |
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.
1 2 3 4 5 6 7 8 9 10 |
[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.
1 2 3 4 5 6 |
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:
1 2 3 4 |
<span style="color: #008000;"><strong><code> BigDecimal(10) with Scale 10 toString = 1.0E-9 BigDecimal(10) with Scale 4 toString = 0.0010 </code></strong></span> |
That’s all for Java BigDecimal class.
Reference: API Doc