[英]BigDecimal, division & MathContext - very strange behaviour
CentOs 5.4, OpenJDK Runtime Environment (build 1.6.0-b09) 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 ? 臭虫?
Javadoc for the first situation: 第一种情况的Javadoc:
Returns a BigDecimal whose value is (this / divisor), and whose scale is as specified.
返回一个BigDecimal,其值为(this / divisor),其小数位数已指定。 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: 第二种情况是Javadoc:
Returns a BigDecimal whose value is (this / divisor), with rounding according to the context settings.
返回一个BigDecimal,其值为(this / divisor),并根据上下文设置进行舍入。
referring to the javadoc for MathContext we get: 引用MathContext的javadoc可以得到:
Immutable objects which encapsulate the context settings which describe certain rules for numerical operators, such as those implemented by the BigDecimal class.
不变的对象封装了上下文设置,这些上下文设置描述了数字运算符的某些规则,例如由BigDecimal类实现的规则。 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.
结果将舍入为这种精确的roundingMode:一个RoundingMode对象,该对象指定要用于舍入的算法。
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. 因此,在第一种情况下,您将SCALE指定为2,这意味着您将精度舍入到2个小数位,其中舍入是作为下位函数执行的。 The second calculation has a specified PRECISION of 2, which is rounded to two digits of accuracy, where the rounding is a floor function.
第二个计算的指定精度为2,该精度被舍入为两位数的精度,其中舍入是下位函数。 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.
例如,如果您在MathContext中要求输入4位数字,则回答时将得到66.66。
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. 在这里,您将覆盖MathContext并使用四舍五入。
total.divide(BigDecimal.valueOf(3), new MathContext(2, RoundingMode.FLOOR))
here you set a precision of 2 and receive only 2 digits. 在这里,您将精度设置为2,并且仅接收2位数字。
读取Javadoc的除法(BigDecimal,MathContext)方法,似乎只考虑了上下文的舍入模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.