Search code examples
javabigdecimalcurrency

BigDecimal.add() being ignored


I have code like this

BigDecimal withoutTax, tax, withTax, totalPrice;
totalPrice = new BigDecimal(0.0);
BigDecimal amount = new BigDecimal(String.valueOf(table.getValueAt(table.getSelectedRow(), 3)).replace(",", "."));
BigDecimal price = new BigDecimal(String.valueOf(table.getValueAt(table.getSelectedRow(), 4)).replace(",", "."));
withoutTax = amount.multiply(price, new MathContext(5));
table.setValueAt(withoutTax.toPlainString(), table.getSelectedRow(), 5);
tax = withoutTax.multiply(new BigDecimal(0.23), new MathContext(2));
table.setValueAt(tax.toPlainString(), table.getSelectedRow(), 7);
withTax = withoutTax.add(tax, new MathContext(5));
table.setValueAt(withTax.toPlainString(), table.getSelectedRow(), 8);
totalPrice.add(withTax, new MathContext(5));
paymentNum.setText(String.valueOf(totalPrice.toPlainString()));

why am I receiving that totalPrice.add is ignored while withoutTax.add is working properly?


Solution

  • That's answered by looking at the docs for BigDecimal

    Returns a BigDecimal whose value is (this + augend), and whose scale is max(this.scale(), augend.scale()).

    Emphasis mine. So add doesn't modify the existing BigDecimal - it can't, since BigDecimals are immutable. According to the docs, BigDecimals are

    Immutable, arbitrary-precision signed decimal numbers.

    Instead of modifying its value, it returns a new value which is equal to the result of the addition.

    Change this:

    totalPrice.add(withTax, new MathContext(5));
    

    to this:

    totalPrice = totalPrice.add(withTax, new MathContext(5));
    

    to assign that new value back to the same variable, and it will correctly update like you expect.

    Compare that to this line:

    withTax = withoutTax.add(tax, new MathContext(5));
    

    You wouldn't expect the value of withoutTax to change simply because you used it in a calculation. In order for that line to work as expected, the add method cannot be allowed to modify the object it is called on.