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.

```
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.

`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);`

`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`

`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`

:

- 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:

```
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.`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:

`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.`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
```

`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

`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`

`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`BigDecimal divide(BigDecimal divisor, int roundingMode)`

: Computes division of`this`

and`divisor`

and returns the output with provided roundingMode.`BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)`

: Computes division of`this`

and`divisor`

and returns the output with provided roundingMode and scale.`BigDecimal multiply(BigDecimal multiplicand)`

: Computes multiplication of`this`

and`multiplicand`

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:

```
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