在java中舍入到最接近的0.05的最佳方法

时间:2012-08-05 08:51:54

标签: java bigdecimal rounding

考虑到除食品外的所有商品均适用10%的税。此外,进口商品还需缴纳5%的附加税。

如果音乐CD的费用是12.49。该项目的税金为1.499。 如果进口香水瓶的成本为47.50,则该项目的税率为7.125

有一项政策规定,项目的税金应四舍五入至最接近的0.05。因此,1.499应四舍五入为1.5,7.125应四舍五入为7.25。

上述舍入要求可以使用逻辑来实现:

    (float) Math.ceil(taxAmount / 0.05f) * 0.05f;

将税项添加到项目的成本中:

音乐CD:12.49 + 1.5 = 13.99 进口巧克力盒:47.50 + 7.25 = 54.65。

我面临以下输入的问题:

如果进口巧克力盒的成本为11.85,则税率为0.5925

使用舍入政策,四舍五入后的税率为0.6。

当我们添加11.85 + 0.6这两个都是浮点数时,我们得到结果为12.450001。与其他输入不同,此特定输入提供了大量小数位,而不是其他输出中的2位小数。

我尝试使用BigDecimal而不是float来存储所有值,并将比例设置为2位小数。这种方法的问题是,如果未指定舍入策略,bigDecimal将在某些情况下抛出异常。为BigDecimal提供舍入策略会导致项目的总成本和适用的税收使用提供给BigDecimal的舍入策略进行舍入,从而改变所需的输出。

3 个答案:

答案 0 :(得分:8)

您可以使用long代替double来使用您可以执行的双重

double d = Math.round(d * 20) / 20.0; // round up to multiple of 0.05

使用long(如美分)

long l = (l + 3) / 5 * 5;

尽管通常认为使用intlongBigDecimal的大多数投资银行和基金使用double是最佳做法,因为一旦您了解如何安全使用它们,比使用更简单(比长)和更快(比BigDecimal)。

答案 1 :(得分:2)

将货币金额存储为整数(例如,分数)。

这是一个常见问题 - 谷歌会给你很多很好的解释。

这是一个:Why not use Double or Float to represent currency?

答案 2 :(得分:0)

这似乎是着名的技术面试问题的一部分 关键是要了解你必须计算税额并将该金额舍入到0.05的上限 计算舍入我使用这个groovy脚本

import java.math.*

def myRound(BigDecimal d){ 
    def scale = new BigDecimal("0.05")
    def y = d.divide(scale)
    println "y :$y"
//    def q = y.round(new MathContext(0,RoundingMode.UP))
    def q = y.setScale(0,BigDecimal.ROUND_UP)
    println "q :$q (intero)"
    def z = q.multiply(scale)
    println "z :$z"
    return z
}

def taxBy(BigDecimal d,BigDecimal t){ 
    return myRound(d.multiply(t))
}
def importTax(BigDecimal d){ 
    return taxBy(d,new BigDecimal("0.15"))
}

def importBaseTax(BigDecimal b){ 
    return taxBy(d,new BigDecimal("0.05"))
}

ip = new BigDecimal("27.99")
ipt = importTax(ip)

println "${ip}-->${ipt} = ${ip+ipt}"

我希望这有用!