Java 使用setScale()方法舍入BigDecimal:意外结果

Java 使用setScale()方法舍入BigDecimal:意外结果,java,rounding,bigdecimal,Java,Rounding,Bigdecimal,要对数字进行四舍五入,我使用以下代码: public static roundBd(BigDecimal bd){ BigDecimal result1 = bd.setScale(0, RoundingMode.HALF_UP); return result1; } 输入1.50-->输出2 输入1.499-->输出1 第一个结果对我来说还可以,但第二个结果不是我所期望的。 即使对于1.499,我也希望在输出2中包含。(详细内容:首先我想将1.499调整为1.50,然后调整为1.

要对数字进行四舍五入,我使用以下代码:

public static roundBd(BigDecimal bd){
  BigDecimal result1 = bd.setScale(0, RoundingMode.HALF_UP);
  return result1;
}
  • 输入1.50-->输出2
  • 输入1.499-->输出1
第一个结果对我来说还可以,但第二个结果不是我所期望的。 即使对于1.499,我也希望在输出2中包含。(详细内容:首先我想将1.499调整为1.50,然后调整为1.5,最后调整为2)

但是

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

这不是四舍五入的工作方式。半整数表示如果一个数字正好位于2个最近可用值之间(取决于刻度),它将被舍入。其他任何内容都四舍五入到最接近的值

摘录自:

舍入模式:向“最近邻居”舍入,除非两个邻居距离相等

要达到您所要求的行为,您可以依次进行轮换,尽管我不确定您为什么想要这样的行为:

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

这不是四舍五入的工作方式。半整数表示如果一个数字正好位于2个最近可用值之间(取决于刻度),它将被舍入。其他任何内容都四舍五入到最接近的值

摘录自:

舍入模式:向“最近邻居”舍入,除非两个邻居距离相等

要达到您所要求的行为,您可以依次进行轮换,尽管我不确定您为什么想要这样的行为:

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

这个结果正是你应该得到的;舍入每个中间值会牺牲精度,因此它会直接舍入到正确的位数

如果你真的想要另一种行为,你必须做如下的事情

while(number.scale() > 0) {
  number.setScale(number.scale() - 1, RoundingMode.HALF_UP);
}

这个结果正是你应该得到的;舍入每个中间值会牺牲精度,因此它会直接舍入到正确的位数

如果你真的想要另一种行为,你必须做如下的事情

while(number.scale() > 0) {
  number.setScale(number.scale() - 1, RoundingMode.HALF_UP);
}

路易丝,再想想你是对的,前面的代码做了应该做的事情。但我需要对欧元币值进行四舍五入。规则规定1.499应该四舍五入到1.50。如果我想把它四舍五入到整数,我应该得到2。路易斯,再想想你是对的,前面的代码应该做什么。但我需要对欧元币值进行四舍五入。规则规定1.499应该四舍五入到1.50。如果我想把它四舍五入到整数,我应该得到2。亚西尔亚斯,你说得对。但我需要对欧元币值进行四舍五入。规则规定1.499应该四舍五入到1.50。那么如果我想把它四舍五入到整数,我应该得到2。@andreaborogelliavveduti好的-那么我给出的例子应该满足您的需要。或者更准确地说,您应该将所有货币金额四舍五入到小数点后2位,这是您的“官方”值。然后使用该值并执行您想要/需要的操作,包括如果愿意,将其舍入到小数点后0位。我的JUnit测试表明,这是欧元舍入的正确解决方案。谢谢你,亚西莉亚,你说得对。但我需要对欧元币值进行四舍五入。规则规定1.499应该四舍五入到1.50。那么如果我想把它四舍五入到整数,我应该得到2。@andreaborogelliavveduti好的-那么我给出的例子应该满足您的需要。或者更准确地说,您应该将所有货币金额四舍五入到小数点后2位,这是您的“官方”值。然后使用该值并执行您想要/需要的操作,包括如果愿意,将其舍入到小数点后0位。我的JUnit测试表明,这是欧元舍入的正确解决方案。谢谢。从这个四舍五入的样式1.4445将四舍五入为2。这不是我们想要的。从四舍五入样式1.4445将四舍五入为2。这不是我们想要的。