Kit Sunde
Kit Sunde

Reputation: 37055

Why does BigDecimal divide cause rounding when it should fit within the significant digits?

Why does BigDecimal divide cause rounding to happen even though the value should fit comfortably in 4 significant digits?

BigDecimal realPercent = new BigDecimal(1.25, new MathContext(4));
// 1.25
BigDecimal percentDivider = new BigDecimal(100, new MathContext(4));
realPercent = realPercent.divide(percentDivider, BigDecimal.ROUND_HALF_UP);
// 0.01

It's possible to make divide behave like I want by setting the precision on the method call, but it doesn't explain why it doesn't already do it.

realPercent.divide(percentDivider, 4, BigDecimal.ROUND_HALF_UP)
// 0.0125

Upvotes: 0

Views: 3128

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1499770

From the Javadoc of divide(BigDecimal, RoundingMode):

Returns a BigDecimal whose value is (this / divisor), and whose scale is this.scale()

The last part is important - the scale of your initial value is 2 (the unscaled value is 125). Because you've called an overload that pins the scale, the closest result available is scale=2, unscaled=1, i.e. 0.01.

Upvotes: 2

Hendrik
Hendrik

Reputation: 5310

By explicitly setting the rounding mode in your divide call here:

realPercent = realPercent.divide(percentDivider, BigDecimal.ROUND_HALF_UP);

you override the used MathContext. If you specify the MathContext with rounding mode right away, it works as expected:

BigDecimal realPercent = new BigDecimal(1.25, new MathContext(4, RoundingMode.HALF_UP));
// 1.25
BigDecimal percentDivider = new BigDecimal(100, new MathContext(4, RoundingMode.HALF_UP));
realPercent = realPercent.divide(percentDivider);
//0.0125

Upvotes: 1

Related Questions