如何解决 Java 四舍五入问题

2022-08-31 11:56:26

似乎减法触发了某种问题,并且结果值是错误的。

double tempCommission = targetPremium.doubleValue()*rate.doubleValue()/100d;

78.75 = 787.5 * 10.0/100d

double netToCompany = targetPremium.doubleValue() - tempCommission;

708.75 = 787.5 - 78.75

double dCommission = request.getPremium().doubleValue() - netToCompany;

877.849999999999 = 1586.6 - 708.75

生成的预期值将为 877.85。

应采取哪些措施来确保计算正确?


答案 1

要控制浮点算术的精度,您应该使用java.math.BigDecimal。阅读John Zukowski的The Need for BigDecimal以获取更多信息。

给定您的示例,最后一行将如下所示,使用 BigDecimal。

import java.math.BigDecimal;

BigDecimal premium = BigDecimal.valueOf("1586.6");
BigDecimal netToCompany = BigDecimal.valueOf("708.75");
BigDecimal commission = premium.subtract(netToCompany);
System.out.println(commission + " = " + premium + " - " + netToCompany);

这将产生以下输出。

877.85 = 1586.6 - 708.75

答案 2

如前所述,这是执行浮点算术的结果。

正如之前的海报所建议的那样,当您进行数值计算时,请使用 。java.math.BigDecimal

但是,使用有一个问题。从双精度值转换为 时,可以选择使用新的构造函数或静态工厂方法。使用静态工厂方法。BigDecimalBigDecimalBigDecimal(double)BigDecimal.valueOf(double)

双构造函数将 的整个精度转换为 a,而静态工厂有效地将其转换为 a,然后将其转换为 .doubleBigDecimalStringBigDecimal

当您遇到这些细微的舍入错误时,这变得相关。数字可能显示为 .585,但在内部其值为“0.5849999999999999996447286321199499070644378662109375”。如果使用构造函数,则将获得不等于 0.585 的数字,而静态方法将给出的值等于 0.585。BigDecimal

double value = 0.585;
System.out.println(new BigDecimal(value));
System.out.println(BigDecimal.valueOf(value));

在我的系统上给出

0.58499999999999996447286321199499070644378662109375
0.585