如何用Java处理BigDecimal中的路由

时间:2019-04-16 01:11:13

标签: java bigdecimal

我有以下代码来获取百分比:

final BigDecimal price = BigDecimal.valueOf(215).setScale(2, BigDecimal.ROUND_HALF_EVEN);
final BigDecimal daysOfThisReservation = BigDecimal.valueOf(3).setScale(2, BigDecimal.ROUND_HALF_EVEN);

final BigDecimal dayPrice = price.divide(daysOfThisReservation, BigDecimal.ROUND_HALF_EVEN).setScale(2, BigDecimal.ROUND_HALF_EVEN);

System.out.println(dayPrice); //71.67
System.out.println(dayPrice.multiply(daysOfThisReservation).setScale(2, BigDecimal.ROUND_HALF_EVEN)); //215.01

我的预订费用为$ 215.00,每天预订3次, 因此价格为71.67美元。

如果我再次尝试获得原始值,则四舍五入会遇到一些问题,71.67 * 3 = 215.01

如何处理此类问题?

3 个答案:

答案 0 :(得分:2)

让我们这样看。内存和通讯很便宜。

BigDecimal totalPrice = new BigDecimal(double 215.00);
int numNight = 3;
BigDecimal perNightPrice = totalPrice
    .divide(new BigDecimal(int numNight), BigDecimal.ROUND_HALF_EVEN)
    .setScale(2, BigDecimal.ROUND_HALF_EVEN);

此时,您具有三个变量。鉴于内存(主RAM和辅助磁盘/ DB)和通信都很便宜,您只需保留totalPrice变量即可。您无需从perNightPrice和numNight对它进行反向工程。

我以前曾遇到过这种情况。我们只是更改了API和/或数据表定义,以允许我们保留更多数据(除非您要在Lunar-Lander中寻找内存,否则我会怀疑,因为Lunar-Lander不计算酒店价格) 。

答案 1 :(得分:2)

我的感觉是,这里的问题不是丢弃原始价格之一,而是通过将小数点后的值舍去到两位小数来丢弃有价值的信息。如果您再保留一位小数,就不会有这个问题。

这里是一个示例,该示例保留6个精度位,以允许足够的精度对值进行数百次运算,而对于这些值,我最终只需要两个有效的小数位。如果您只关心最后2位,则永远不会出现小数点后6位的舍入问题。

除了打印单日价格时,该代码保留6位,这时四舍五入到2位。

final BigDecimal price = BigDecimal.valueOf(215).setScale(6, BigDecimal.ROUND_HALF_EVEN);
final BigDecimal daysOfThisReservation = BigDecimal.valueOf(3).setScale(6, BigDecimal.ROUND_HALF_EVEN);

final BigDecimal dayPrice = price.divide(daysOfThisReservation, BigDecimal.ROUND_HALF_EVEN).setScale(6, BigDecimal.ROUND_HALF_EVEN);

System.out.println(dayPrice.setScale(2, BigDecimal.ROUND_HALF_EVEN));
System.out.println(dayPrice.multiply(daysOfThisReservation).setScale(2, BigDecimal.ROUND_HALF_EVEN)); //215.01

结果:

71.67
215.00

答案 2 :(得分:1)

可以提高到一定精度吗?

final BigDecimal price = BigDecimal.valueOf(215).setScale(10, BigDecimal.ROUND_HALF_EVEN);
final BigDecimal daysOfThisReservation = BigDecimal.valueOf(3).setScale(10, BigDecimal.ROUND_HALF_EVEN);
相关问题