2

Can someone explain why those two have different results?

BigDecimal bd1 = new BigDecimal(1234.5678)
    .divide(
        new BigDecimal(1.19),
        4,
        RoundingMode.CEILING
    );
BigDecimal bd2 = new BigDecimal(1234.5678)
    .divide(
        new BigDecimal(1.19),
        new MathContext(4, RoundingMode.CEILING)
    );

Result:

bd1: 1037.4520
bd2: 1038
Slava Vedenin
  • 58,326
  • 13
  • 40
  • 59
tzortzik
  • 4,993
  • 9
  • 57
  • 88
  • 1
    I take it the MCVE I put together for you demonstrates the problem? – Michael Dec 10 '18 at 10:55
  • You made the example worse. Don't use double literals for BigDecimal constructors if you can avoid it. Floating point precision makes the example **less** clear. `1234.5678` will not be `1234.5678`. – Michael Dec 10 '18 at 10:58
  • @Michael That is the point. My real example is something similar. I have something like 2074523.35687 as input – tzortzik Dec 10 '18 at 11:01
  • Use a string then – Michael Dec 10 '18 at 11:01

1 Answers1

5

Because in MathContext(4, RoundingMode.CEILING), 4 is precision, but in .divide(new BigDecimal(1.19), 4, RoundingMode.CEILING);, 4 is scale. You can see difference between "precision" and "scale" here

One important point that is alluded to but not directly addressed is the difference between "precision" and "scale" and how they are used in the two statements. "precision" is the total number of significant digits in a number. "scale" is the number of digits to the right of the decimal point.

So if you change second one to

final BigDecimal bd2 = new BigDecimal(1234.5678)
        .divide(
                new BigDecimal(1.19),
                new MathContext(8, RoundingMode.CEILING)
        );

You have same results:

1037.4520
1037.4520
Slava Vedenin
  • 58,326
  • 13
  • 40
  • 59