BigDecimal的缩放和舍入问题

时间:2015-07-22 08:08:56

标签: java scale rounding bigdecimal

基本上我写了一个BigDecimal实例的倒数值的方法:

public class Main{

public static void main(String[] args) {

    BigDecimal value1 = new BigDecimal("88");
    BigDecimal reciproc1 = reciproc(value1);
    BigDecimal reciproc2 = reciproc(reciproc1);
    System.out.println("Initial value: " + value1);
    System.out.println("Reciproc1: " + reciproc1);
    System.out.println("Reciproc2: " + reciproc2);
}

public static BigDecimal reciproc(BigDecimal value) throws ArithmeticException{
    if (value.equals(new BigDecimal("0"))){
        throw new ArithmeticException("Cannot divide by zero");
    }
    return new BigDecimal("1").divide(value, 20, RoundingMode.HALF_UP);
}

}

输出将如下:

Initial value: 88
Reciproc1: 0.01136363636363636364
Reciproc2: 87.99999999999999997185

很明显,变量reciproc2必须等于初始值。不幸的是,我的方法并非如此。 我试图通过操纵缩放和舍入模式来解决这个问题,但我所有的尝试都是徒劳的:

return new BigDecimal("1").divide(value, 3, RoundingMode.HALF_UP);
Reciproc2: 90.909

return new BigDecimal("1").divide(value, 15, RoundingMode.CEILING);
Reciproc2: 87.9999999999999999999995073

1 个答案:

答案 0 :(得分:0)

可能不是您正在寻找的解决方案,但是使用Apache commons-lang Fraction可能会很方便:

public static void main(String[] args) {
    Fraction value1 = Fraction.getFraction(88, 1);
    Fraction reciproc1 = reciproc(value1);
    Fraction reciproc2 = reciproc(reciproc1);
    System.out.println("Initial value: " + value1.toProperString() + " " + value1.doubleValue());
    System.out.println("Reciproc1: " + reciproc1.toProperString() + " " + reciproc1.doubleValue());
    System.out.println("Reciproc2: " + reciproc2.toProperString() + " " + reciproc2.doubleValue());
}

public static Fraction reciproc(Fraction value) throws ArithmeticException{
    if (value.equals(Fraction.ZERO)){
        throw new ArithmeticException("Cannot divide by zero");
    }
    return Fraction.ONE.divideBy(value);
}

哪个输出:

Initial value: 88 88.0
Reciproc1: 1/88 0.011363636363636364
Reciproc2: 88 88.0