开发者

BigDecimal, division & MathContext - very strange behaviour

CentOs 5.4, OpenJDK Runtime Environment (build 1.6.0开发者_JAVA百科-b09)

MathContext context = new MathContext(2, RoundingMode.FLOOR);  
BigDecimal total = new BigDecimal("200.0", context);

BigDecimal goodPrice = total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR);
System.out.println("divided price=" + goodPrice.toPlainString());
// prints 66.66

BigDecimal goodPrice2 = total.divide(BigDecimal.valueOf(3), new MathContext(2,    RoundingMode.FLOOR));
System.out.println("divided price2=" + goodPrice2.toPlainString());
// prints 66

BUG ?


Javadoc for the first situation:

Returns a BigDecimal whose value is (this / divisor), and whose scale is as specified. If rounding must be performed to generate a result with the specified scale, the specified rounding mode is applied.

and the Javadoc for the second situation:

Returns a BigDecimal whose value is (this / divisor), with rounding according to the context settings.

referring to the javadoc for MathContext we get:

Immutable objects which encapsulate the context settings which describe certain rules for numerical operators, such as those implemented by the BigDecimal class. The base-independent settings are: precision: the number of digits to be used for an operation; results are rounded to this precision roundingMode: a RoundingMode object which specifies the algorithm to be used for rounding.

So in the first case, you specified a SCALE of 2, meaning that you round to 2 decimal places of accuracy, where the rounding is performed as a floor function. The second calculation has a specified PRECISION of 2, which is rounded to two digits of accuracy, where the rounding is a floor function. So, in the first case, you asked for 2 digits after the decimal place, and in the second, you just asked for 2 digits. If, for example, you had asked for 4 digits in your MathContext, you'd get 66.66 as you answer.

So I don't think that this is a bug so much as that the two methods don't perform the same calculation.


This is completely the expected behavior. I think you make the mistake and mix rounding(scale) and precision.

total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR)

here you override your the MathContext and use a rounding.

total.divide(BigDecimal.valueOf(3), new MathContext(2,    RoundingMode.FLOOR))

here you set a precision of 2 and receive only 2 digits.


Reading the Javadoc for the divide(BigDecimal, MathContext) method, it seems that only the rounding mode of the context is taken into account.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜