Division of BigDecimals

Viewed 169

I want to use BigDecimal in some calculations. Imagine that in some intermediate step there is the following division new BigDecimal(1).divide(new BigDecimal(4)). I understand that in this case the scale is calculated automatically and the result is 0.25. But Imagine that in some cases this fraction cannot be represented as a decimal expanstion like in new BigDecimal(1).divide(new BigDecimal(3)) then this exception is thrown java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. cause no scale was set.

My question is: I don't want to force a fixed scale when it is not necessary, but I don't want it to throw an exception either. How can I accomplish that? Is there a way to say "Use this scale when you don't know what to do"?. If so, how can I do that, and what would be a reasonable value for the scale in an interest calculation?

3 Answers

There's no ergonomic setting in the API as far as I'm aware, but why not just do:

try { 
   //do you're thing
} catch(ArithmeticException e) {
   //if it fails, then set the scale 
   x.setScale(...)
}

You need to first check what is the nature of the result of the division. If it is a price, then set the scale to 2 beforehand. If it is a rate (e.g. an exchange rate, an interest rate, etc.) then choose a suitable scale to make your calculations sufficiently precise, and then you can call stripTrailingZeros if you like to make the presentation nicer:

BigDecimal.valueOf(1).divide(BigDecimal.valueOf(3), 8, RoundingMode.HALF_EVEN)
    ➛ 0.33333333
BigDecimal.valueOf(1).divide(BigDecimal.valueOf(4), 8, RoundingMode.HALF_EVEN)
    ➛ 0.25000000
BigDecimal.valueOf(1).divide(BigDecimal.valueOf(4), 8, RoundingMode.HALF_EVEN)
        .stripTrailingZeros()
    ➛ 0.25

However, if you are changing the scale purely for presentational reasons, I would prefer to leave the scale at a constant 2 for prices and 8 (or higher) for rates, and then use suitable formatting to suppress trailing zeros when you eventually come to printing out the values:

new DecimalFormat("#.##########").format(new BigDecimal("12.340000000"))
    ➛ "12.34"

There is no other possible way's that's why ArithmeticException introduced.

either you need to use scale.

a.divide(b, 2, RoundingMode.HALF_EVEN)

or Catch an Exception and perform the custom operation as explained by @Amir.

Related