You seem to be missing two things:
- For the value: using
new MathContext(3)
when adding causes the value to be rounded to three digits. First you add 8024, and the sum, 8024, is rounded to 8020. Everything beyond the first three digits is set to 0, rounding up or down. Then you add 8024 again, and the sum, 16044, is rounded to 16000.
- For the output format: When you print a
BigDecimal
, you are (implicitly or explicitly) calling its toString
method. This method very often produces the scientific notation that you got. The exact rules for when it does are in the documentation, see the link at the bottom. If you want to be sure to control the format of your BigDecimal
, use a DecimalFormat
.
- Not related to your unwanted output in this example: You are misusing
AtomicReference
when in your addition first doing a get()
and then a set()
. In a multi-threaded environment (which is where AtomicReference
makes any sense) a different thread may do a set()
or other operation between those two calls, but the result of that would get lost when you do set()
. Instead you should use the accumulateAndGet
(or getAndAccumulate
) method of AtomicReference
.
I also don’t understand why you were doing things in such a complicated way. This simpler way gives you what you ask for:
List<BigDecimal> list = List.of(new BigDecimal("8024"), new BigDecimal("8024"));
BigDecimal totalAmount = BigDecimal.ZERO;
for (BigDecimal value : list) {
totalAmount = totalAmount.add(value);
}
System.out.println(totalAmount);
Output is:
16048
It’s similar to the code in the other answer.
Edit: As a matter of good habit I am passing string literals to new BigDecimal()
. While passing an integer literal such as 8024 poses no problem in itself, passing a double literal, for example 8024.1, often implies an inaccuracy. Passing a string will always give you a BigDecimsl
holding the exact same value as the string.
Documentation links