BigDecimal的,分裂与MathContext的 - 很奇怪的行为
-
22-09-2019 - |
题
5.4 CENTOS, 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?
解决方案
JavaDoc规定的第一种情况:
返回BigDecimal,其值为(this /除数), 并且其规模的规定。如果必须执行以生成与指定的规模的结果舍入,指定的舍入模式被应用。
和用于第二情况的Javadoc:
返回BigDecimal,其值为(this /除数), 与根据上下文设置进行舍入。
指为MathContext的javadoc中我们得到:
不可变对象,其封装 上下文设置其描述 数字运算符一定的规则, 如那些由实施 BigDecimal类。 该基地无关 设置有:精密:数量 数字将被用于的操作; 结果舍入到此精度 则roundingMode:一个对象的RoundingMode 它指定该算法是 用于舍入。
因此,在第一种情况下,指定为2的SCALE,这意味着你轮精度的2位小数,其中所述舍入为一个整函数执行。第二计算具有2的指定的精度,这是四舍五入到精度两个数字,其中舍入是下取整函数。因此,在第一种情况下,你自找的2位的小数点后的,而在第二,你刚才问了2个位数。如果,例如,你曾要求在你的MathContext 4位,你会得到66.66为你解答。
所以,我不认为这是一个错误这么多,这两种方法不执行相同的计算。
其他提示
这完全是预期的行为。我想你犯错误和混合四舍五入(规模)和精度。
total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR)
在这里你重写你的MathContext的,并使用一个圆。
total.divide(BigDecimal.valueOf(3), new MathContext(2, RoundingMode.FLOOR))
这里设置为2的精确度和仅接收2位数字。
读的Javadoc除法(BigDecimal的,的MathContext)方法,它似乎只有上下文的舍入模式被考虑在内。
不隶属于 StackOverflow