将大十进制四舍五入到最接近的5美分

2022-09-02 02:08:28

我试图弄清楚如何将货币金额向上舍入到最接近的5美分。下面显示了我的预期结果

1.03     => 1.05
1.051    => 1.10
1.05     => 1.05
1.900001 => 1.10

我需要结果的精度为2(如上所示)。

更新

按照下面的建议,我能做的最好的事情就是这个

    BigDecimal amount = new BigDecimal(990.49)

    // To round to the nearest .05, multiply by 20, round to the nearest integer, then divide by 20
   def result =  new BigDecimal(Math.ceil(amount.doubleValue() * 20) / 20)
   result.setScale(2, RoundingMode.HALF_UP)

我不相信这是100%的犹太洁食 - 我担心在转换成双打时可能会失去精度。但是,这是我迄今为止想到的最好的,似乎有效。


答案 1

使用没有任何双打(改进了马可洛普斯的答案):BigDecimal

public static BigDecimal round(BigDecimal value, BigDecimal increment,
                               RoundingMode roundingMode) {
    if (increment.signum() == 0) {
        // 0 increment does not make much sense, but prevent division by 0
        return value;
    } else {
        BigDecimal divided = value.divide(increment, 0, roundingMode);
        BigDecimal result = divided.multiply(increment);
        return result;
    }
}

舍入模式例如。对于您的示例,您实际上想要( 是一个返回的助手):RoundingMode.HALF_UPRoundingMode.UPbdnew BigDecimal(input)

assertEquals(bd("1.05"), round(bd("1.03"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.10"), round(bd("1.051"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.05"), round(bd("1.05"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.95"), round(bd("1.900001"), bd("0.05"), RoundingMode.UP));

另请注意,上一个示例中存在错误(将 1.900001 舍入为 1.10)。


答案 2

我会尝试乘以20,四舍五入到最接近的整数,然后除以20。这是一个黑客,但应该给你正确的答案。