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
BUG?
答案 0 :(得分:9)
第一种情况的Javadoc:
返回一个BigDecimal,其值为(this / divisor), 其规模如指定。如果必须执行舍入以生成具有指定比例的结果,则应用指定的舍入模式。
和第二种情况的Javadoc:
返回一个BigDecimal,其值为(this / divisor), 根据上下文设置进行舍入。
引用我们得到的MathContext的javadoc:
封装的不可变对象 描述的上下文设置 数值算子的某些规则, 比如那些实施的 BigDecimal类。 与基地无关 设置有:精度:数量 用于操作的数字; 结果四舍五入到此精度 roundingMode:一个RoundingMode对象 它指定了算法 用于四舍五入。
因此,在第一种情况下,您指定SCALE为2,这意味着您将舍入到精度的2位小数,其中舍入作为floor函数执行。第二个计算具有指定的PRECISION为2,其四舍五入为精度的两位数,其中舍入为floor函数。因此,在第一种情况下,您在小数位后面要求 ,而在第二种情况下,您只需要2位数。例如,如果您在MathContext中要求4位数字,则在回答时会得到66.66。
所以我认为这不是一个错误,因为这两个方法不会执行相同的计算。
答案 1 :(得分:2)
这完全是预期的行为。我认为你犯了错误并混合了舍入(比例)和精度。
total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR)
在这里你覆盖你的MathContext并使用舍入。
total.divide(BigDecimal.valueOf(3), new MathContext(2, RoundingMode.FLOOR))
这里设置精度为2,只接收2位数。
答案 2 :(得分:0)
为了除法(BigDecimal,MathContext)方法读取Javadoc,似乎只考虑了上下文的舍入模式。