# Overflowing BigDecimals

If you do a lot of numerical calculations in Java where control over precision and rounding is important (especially currency-related calculations), the BigDecimal class should be your first port of call. They encapsulate an integer unscaled value, and a 32-bit precision scaling factor, which provides a large range of values.

If we define a variable called `dividendTax` as a BigInteger like so:

`private BigDecimal dividendTax;`

with a scaling factor of 2 (for currency) and a suitable rounding mode:

```static final Integer SCALE = 2; public static final RoundingMode ROUND_MODE = RoundingMode.HALF_UP; ```

We can round and scale an intermediate BigInteger-based calculation to a Double value like so:

``` public Double getDividendTax() { return dividendTax.setScale(Constants.SCALE, Constants.ROUND_MODE).doubleValue(); }```

Operations like divide() are methods on the BigDecimal instances themselves:

```public Double getMonthlyTaxableAmount() { return annualDividendTax.divide(new BigDecimal(12.0).setScale(Constants.SCALE, Constants.ROUND_MODE).doubleValue(); } ```

The above code snippet is possibly dangerous, in that the divide() operation can throw an ArithmeticException if the result from divide() is an infinite expansion (e.g. 1 divided by 3). This happened to me a couple of times until I figured what was missing.

The key is to pass a MathContext instance which specifies the correct precision to use. By default, the BigDecimal arithmetical operators use unlimited precision, which will obviously fail if a division operation results in an infinite series. So you need to truncate the results using one of the predefined precision ranges:

```public Double getMonthlyTaxableAmount() { return annualDividendTax.divide(new BigDecimal(12.0), MathContext.DECIMAL32).setScale(Constants.SCALE, Constants.ROUND_MODE).doubleValue(); } ```

Keep this in mind if you are using division operations that may potentially give infinite-precision results.