Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bigdecimal for financial calculations and non-terminating computations

I'm sure this would be a simple question to answer but I can't for the life of me decide what has to be done. So here's it: assuming we follow the "best practice" of using BigDecimal for financial calculations, how can one handle stuff (computations) which throw an exception?

As as example: suppose, I have to split a "user amount" for investing in bonds between "n" different entities. Now consider the case of user submitting $100 for investing to be split between 3 bonds. The equivalent code would look like:

public static void main(String[] args) throws Exception {
    BigDecimal bd1 = new BigDecimal("100.0");
    BigDecimal bd2 = new BigDecimal("3");
    System.out.println(bd1.divide(bd2));
}

But as we all know, this particular code snippet would throw an ArithmeticException since the division is non-terminating. How does one handle such scenarios in their code when using infinite precision data types during computations?

TIA,
sasuke

UPDATE: Given that RoundingMode would help remedy this issue, the next question is, why is 100.0/3 not 33.33 instead of 33.3? Wouldn't 33.33 be a "more" accurate answer as in you expect 33 cents instead of 30? Is there any way wherein I can tweak this?

like image 424
sasuke Avatar asked Dec 28 '22 13:12

sasuke


2 Answers

The answer is to use one of the BigDecimal.divide() methods which specify a RoundingMode.

For example, the following uses the rounding mode half even or bankers rounding (but half up or one of the other rounding modes may be more appropriate depending on requirements) and will round to 2 decimal places:

bd1.divide(bd2, 2, RoundingMode.HALF_EVEN);
like image 88
krock Avatar answered Feb 07 '23 18:02

krock


divide has an overload that takes a rounding mode. You need to choose one. I believe "half even" is the most commonly used one for monetary calculations.

like image 32
Chris Jester-Young Avatar answered Feb 07 '23 18:02

Chris Jester-Young