I am working with BigDecimal
and I know that if I divide I have to use MathContext
and tell which Scale
and RoundingMode
to avoid ArithmeticException
as described in the documentation:
In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown.
In the method I'm working on I have to sum amounts coming from our database (that are rounded at 2 decimals) with amounts coming from an external service, and I don't know the exact scaling of these amounts (probabily 3 decimals).
My question is, can I trust BigDecimal
's add method and use it without rounding and scaling or it's a good practice to always specify the desired scale?
Is there any particular case in which addition and subtraction can raise ArithmeticException
?
BigDecimal.add()
will throw ArithmeticException
if the scale of the result does not fit into an int
.
A simple example is adding two numbers with the maximum and the minimum scales:
BigDecimal a = new BigDecimal(BigInteger.ONE, Integer.MIN_VALUE);
BigDecimal b = new BigDecimal(BigInteger.ONE, Integer.MAX_VALUE);
a.add(b);
If your application needs to operate at such scale then you probably have some bigger problems than worrying about arithmetic exception.
Adding numbers without using MathContext
will maintain proper scale and give you the precice result. Depending on the actual values this approach can use arbitrary amount of memory to represent increasingly long numbers, and longer numbers take more time to add.
Adding numbers without using MathContext
and rouding once after the summation will give you the precice result rounded to the requested MathContext
. The memory and computation costs are the same as in the first case.
Using MathContext
for each addition will produce a result which can differ from the presize result by an arbitrary value, but the memory and speed will be more predicatable.
Choosing which one of these approaches to use really depends on the nature of the task, so it is up to you to assess and chose the proper approach for each particular case.