java 使用 setScale() 方法舍入 BigDecimal:意外结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11241155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rounding BigDecimal with the setScale() method: unexpected result
提问by Andrea Borgogelli Avveduti
To round a number I use the following code:
要舍入一个数字,我使用以下代码:
public static roundBd(BigDecimal bd){
BigDecimal result1 = bd.setScale(0, RoundingMode.HALF_UP);
return result1;
}
- Input 1.50 --> Output 2
- Input 1.499 --> Output 1
- 输入 1.50 --> 输出 2
- 输入 1.499 --> 输出 1
The first result is ok for me, but the second is not what I expected. Even for 1.499 I'd like to have in output 2. (In details: first I'd like to round 1.499 to 1.50 then to 1.5 and finally to 2)
第一个结果对我来说还可以,但第二个结果不是我所期望的。即使对于 1.499,我也希望在输出 2 中使用。(详细说明:首先我想将 1.499 舍入到 1.50,然后到 1.5,最后到 2)
But....
但....
BigDecimal bd = new BigDecimal("1.499"); // I'd like to round it to 2
BigDecimal result1 = bd.setScale(2, RoundingMode.HALF_UP); // result1 == 1.50
BigDecimal result2 = bd.setScale(1, RoundingMode.HALF_UP); // result2 == 1.5
BigDecimal result3 = bd.setScale(0, RoundingMode.HALF_UP); // result3 == 1
回答by assylias
That's not the way rounding works. HALF_UP means that if a number is exactly in the middle between the 2 closest available values (depending on the scale), it will be rounded up. Anything else is rounded to the closest value.
这不是四舍五入的工作方式。HALF_UP 意味着如果一个数字正好位于 2 个最接近的可用值之间(取决于比例),它将被四舍五入。其他任何内容都四舍五入到最接近的值。
Extract from the javadoc:
从javadoc 中提取:
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant
舍入模式向“最近的邻居”舍入,除非两个邻居等距
To get to the behaviour you require, you could round successively although I'm not sure whyyou want such a behaviour:
为了达到您需要的行为,您可以连续四舍五入,尽管我不确定您为什么想要这样的行为:
BigDecimal bd = new BigDecimal("1.499"); // I'd like to round it to 2
BigDecimal result1 = bd.setScale(2, RoundingMode.HALF_UP); // result1 == 1.50
BigDecimal result2 = result1.setScale(0, RoundingMode.HALF_UP); // result2 == 2
回答by Louis Wasserman
This result is exactly what you shouldget; rounding each intermediate sacrifices precision, so it rounds directly to the correct number of digits.
这个结果正是你应该得到的;四舍五入每个中间牺牲精度,所以它直接四舍五入到正确的位数。
If you really want the other behavior, you'll have to do something like
如果您真的想要其他行为,则必须执行以下操作
while(number.scale() > 0) {
number.setScale(number.scale() - 1, RoundingMode.HALF_UP);
}