Java BigDecimal Round Down问题

时间:2012-08-17 17:32:59

标签: java

我有一些简单的代码可以向上舍入和舍入,但它会产生一些意想不到的结果。

    public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub

    double a = 46.66;
    System.out.println("Roundup: " + roundUp(a,2) + "\nRound Down: " + roundDown(a,2));

}

public static double roundUp(double a, int scale)
{
    BigDecimal value = new BigDecimal(a);
    value = value.setScale(scale, RoundingMode.UP);
    return value.doubleValue();
}

public static double roundDown(double a, int scale)
{
    BigDecimal value = new BigDecimal(a);
    value = value.setScale(scale, RoundingMode.DOWN);
    return value.doubleValue();
}

当我在小数点后使用3位数时,它按预期工作。如果a = 44.661,则输出如下所示。

总结:46.67倒圆:46.66

当a = 44.66时,向下舍入值减1,这是下面意外的。

总结:46.66回合:46.65

如何在保持上述结果的同时获得44.66的舍入值和44.67的roundUp值。

提前感谢您的帮助

3 个答案:

答案 0 :(得分:9)

那是因为你没有真正使用BigDecimals,你使用的是双打。当您键入44.66时,它会转换为double,这会导致值略小于44.66。 BigDecimal无法修复在您输入之前已经发生的舍入错误。

试试这个。

public static void main(String[] args) throws Exception {
    BigDecimal a = new BigDecimal("46.66");
    System.out.println("Roundup: " + roundUp(a,2) + "\nRound Down: " + roundDown(a,2));
}

public static BigDecimal roundUp(BigDecimal a, int scale)
{
    return a.setScale(scale, RoundingMode.UP);
}

public static BigDecimal roundDown(BigDecimal a, int scale)
{
    return a.setScale(scale, RoundingMode.DOWN);
}

答案 1 :(得分:2)

你可以做的是使用BigDecimal.valueOf

向上或向下舍入
 BigDecimal value = BigDecimal.valueOf(a);

这可以补偿双打的表示错误,但是如果你有一些arithemtic舍入错误,这可能还不够。

相反,您需要确定可以拥有的最大舍入误差

public static double roundUp2(double d) {
    return Math.ceil(d * 100 - ERR)/100.0;
}

public static double roundHalf2(double d) {
    return Math.ceil(d * 100)/100.0;
}

public static double roundDown2(double d) {
    return Math.floor(d * 100 + ERR)/100.0;
}

答案 2 :(得分:0)

我相信你真正需要的是做以下功能:

private static function roundUp(double num, int decimalPlaces){

for (int i =0; i< decimalPlaces; ++i){
     num*=10; 
}

int tmp = (int) (num+0.5);
num = tmp;

for (int i =0; i< decimalPlaces; ++i){
     num = num/10; 
}
}

并且您可以使用替代方法进行四舍五入,只需将“num + 0.5”更改为“num - 0.5”即可。由于机器浮动数字错误,打印时可能会导致麻烦。但你也可以为此做点什么。