Round BigDecimal取决于第十位值

时间:2016-10-13 01:22:50

标签: java bigdecimal

假设我有一个可以是任意数量值的BigDecimal。如果第十位值小于3(即12.2,我想向下舍入到12)。如果第十位值大于或等于3(即11.3),我想将第十个值舍入到5,(因此这里的值最终将为11.5)。 BigDecimal是否具有允许轻松实现此功能的现有功能。如果没有,那么有什么好办法可以实现这一目标呢?

2 个答案:

答案 0 :(得分:0)

您可以创建自己的BigDecimal版本并覆盖round方法,但这只会在使用该方法时有所帮助。对于它自然进行的舍入(在进行常规数学运算时),没有简单的方法可以改变它已经提供的舍入行为。如果您查看BigDecimal实现,许多进行舍入的方法都是静态的,因此您将无法覆盖它们。

以下是覆盖round方法的方法。

class MyDecimal extends BigDecimal {

    public MyDecimal(BigInteger val) {
        super(val);
    }

    @Override
    public BigDecimal round(MathContext mc) {

        /* implement your rounding algorithm here*/
    }

}

答案 1 :(得分:0)

您可以先使用BigDecimalsetScale()缩放为10位小数。然后你可以操纵unscaledValue()的最后一位数字:

public class BigDecimalRounder
{
    public static BigDecimal roundToNearestHalf(BigDecimal value)
    {
        // Scale to 10 decimal digits and get the underlying BigInteger:
        BigInteger digits = value.setScale(10, BigDecimal.ROUND_HALF_UP).unscaledValue();

        // Act upon the last digit of the BigInteger:
        BigInteger lastDigit = digits.mod(BigInteger.TEN);
        int intDigit = lastDigit.intValue();
        BigInteger newDigit;

        if (intDigit >= 0 && intDigit <= 2)
            newDigit = BigInteger.ZERO;          // round down
        else if (intDigit >= 3 && intDigit <= 7)
            newDigit = BigInteger.valueOf(5);    // round to nearest 5
        else
            newDigit = BigInteger.TEN;           // round up

        // Assemble a new BigInteger, removing the original last digit and 
        // adding the new one (either 0, 5 or 10) 
        BigInteger newValue = digits.subtract(lastDigit).add(newDigit);

        //Assemble a new BigDecimal with the modified digits.
        return new BigDecimal(newValue, 10);
    }

    public static void main(String[] args)
    {
        BigDecimal mainValue = new BigDecimal("1.2399997990");
        BigDecimal addend = BigDecimal.ONE.movePointLeft(10);
        for (int i = 1; i <= 12; i++)
        {
            System.out.println("" + mainValue + " --> " + roundToNearestHalf(mainValue));
            mainValue = mainValue.add(addend);
        }
    }

}

输出:

1.2399997990 --> 1.2399997990
1.2399997991 --> 1.2399997990
1.2399997992 --> 1.2399997990
1.2399997993 --> 1.2399997995
1.2399997994 --> 1.2399997995
1.2399997995 --> 1.2399997995
1.2399997996 --> 1.2399997995
1.2399997997 --> 1.2399997995
1.2399997998 --> 1.2399998000
1.2399997999 --> 1.2399998000
1.2399998000 --> 1.2399998000
1.2399998001 --> 1.2399998000