0

I am going through JUnit learning and I was doing some basic calculations to see how it works with BigDecimal. Starting with a few values, subtracting them and asserting the final result.

What I found out is that the assertion either fails or passes depending on what I put into the BigDecimal constructor within assertion.

It passes if the last constructor has a String in it:

@Test
public void areCalculationsDoingOkWithBigDecimal(){
    BigDecimal initialBalance = new BigDecimal(5);
    BigDecimal spendingOne = new BigDecimal(0.25);
    BigDecimal spendingTwo = new BigDecimal("0.47");
    BigDecimal spendingThree = new BigDecimal ("1.73");

    BigDecimal finalBalance = initialBalance.subtract(spendingOne).subtract(spendingTwo).subtract(spendingThree);

    System.out.println("Final balance after all the spendings: " + finalBalance);

    assertThat(finalBalance, is(new BigDecimal("2.55")));
}

It fails when the last constructor has a double in it:

@Test
public void areCalculationsDoingOkWithBigDecimal(){
    BigDecimal initialBalance = new BigDecimal(5);
    BigDecimal spendingOne = new BigDecimal(0.25);
    BigDecimal spendingTwo = new BigDecimal("0.47");
    BigDecimal spendingThree = new BigDecimal ("1.73");

    BigDecimal finalBalance = initialBalance.subtract(spendingOne).subtract(spendingTwo).subtract(spendingThree);

    System.out.println("Final balance after all the spendings: " + finalBalance);

    assertThat(finalBalance, is(new BigDecimal(2.55)));
}

At the same time the constructors at the top are a mix of ints, doubles and Strings and it doesn't affect the outcome in any way.

Why would assertion fail depending on the type of the constructor?

I expected assertion to pass in both of the cases. I didn't expect the type of constructor to affect the value of BigDecimal.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
CowOO
  • 31
  • 1
  • 6
  • Not an exact duplicate, but [this question](https://stackoverflow.com/questions/7186204/bigdecimal-to-use-new-or-valueof) covers the topic. – Joachim Sauer Feb 15 '23 at 15:42

1 Answers1

1

See the Javadoc of the BigDecimal(double) constructor: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/math/BigDecimal.html#%3Cinit%3E(double). It explicitly warns about this. I'd wish they'd deprecate the constructor, because I've only had issues with it. I either use the constructor that takes a String, or one of the valueOf methods.

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20