2

CentOs 5.4,OpenJDK 运行时环境(内部版本 1.6.0-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

漏洞 ?

4

3 回答 3

9

第一种情况的Javadoc:

返回一个 BigDecimal,其值为 (this / divisor),其比例为指定的。如果必须执行舍入以生成具有指定比例的结果,则应用指定的舍入模式。

和第二种情况的Javadoc:

返回值为 (this / divisor) 的 BigDecimal,根据上下文设置进行舍入。

参考 MathContext 的 javadoc 我们得到:

封装上下文设置的不可变对象,这些设置描述了数字运算符的某些规则,例如由 BigDecimal 类实现的规则。与基数无关的设置是: 精度:用于操作的位数;结果被四舍五入到这个精度 roundingMode:一个 RoundingMode 对象,它指定用于四舍五入的算法。

所以在第一种情况下,您将 SCALE 指定为 2,这意味着您四舍五入到小数点后 2 位,其中四舍五入是作为底函数执行的。第二个计算的指定 PRECISION 为 2,四舍五入到两位精度,其中四舍五入是一个底函数。因此,在第一种情况下,您要求小数点后两位数,而在第二种情况下,您只要求两位数。例如,如果您在 MathContext 中要求输入 4 位数字,那么您在回答时会得到 66.66。

所以我不认为这是一个错误,因为这两种方法不执行相同的计算。

于 2010-03-27T14:40:40.603 回答
2

这完全是预期的行为。我认为您犯了错误并混合了舍入(比例)和精度。

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

在这里你覆盖你的 MathContext 并使用舍入。

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

在这里,您将精度设置为 2 并且只接收 2 位数字。

于 2010-03-27T14:43:33.450 回答
0

阅读divide(BigDecimal, MathContext)方法的Javadoc,似乎只考虑了上下文的舍入方式。

于 2010-03-27T14:16:25.030 回答