为了账号安全,请及时绑定邮箱和手机立即绑定

如何解决Java舍入双重问题

如何解决Java舍入双重问题

慕妹3242003 2019-07-02 17:18:44
如何解决Java舍入双重问题似乎减法触发了某种问题,其结果是错误的。double tempCommission = targetPremium.doubleValue()*rate.doubleValue()/100d;78.75=787.5*10.0/100 ddouble netToCompany = targetPremium.doubleValue() - tempCommission;708.75 = 787.5 - 78.75double dCommission = request.getPremium().doubleValue() - netToCompany;877.8499999999999 = 1586.6 - 708.75由此产生的期望值为877.85。如何确保计算正确?
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

要控制浮点算法的精度,应使用java.math.BigDecimal..朗读,阅读对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


查看完整回答
反对 回复 2019-07-02
?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

正如前面的答案所述,这是做浮点运算的结果。

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

然而,使用BigDecimal..将双值转换为BigDecimal,您可以选择使用新的BigDecimal(double)构造函数或BigDecimal.valueOf(double)静态工厂法使用静态工厂方法。

双构造函数转换double转到BigDecimal静态工厂有效地将其转换为String,然后将其转换为BigDecimal.

当您遇到这些微妙的舍入错误时,这一点就变得相关了。一个数字可能显示为.585,但在内部它的值是‘0.58499999999999996447286321199499070644378662109375’.如果你用BigDecimal构造函数,您将得到不等于0.585的数字,而静态方法将给出一个等于0.585的值。

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

在我的系统上

0.58499999999999996447286321199499070644378662109375
0.585


查看完整回答
反对 回复 2019-07-02
?
绝地无双

TA贡献1946条经验 获得超4个赞

另一个例子:

double d = 0;for (int i = 1; i <= 10; i++) {
    d += 0.1;}System.out.println(d);    // prints 0.9999999999999999 not 1.0

使用BigDecimal代替。

编辑:

另外,要指出的是,这不是一个‘Java’四舍五入的问题。其他语言表现出类似的(虽然不一定是一致的)行为。Java至少保证了这方面的一致行为。


查看完整回答
反对 回复 2019-07-02
  • 3 回答
  • 0 关注
  • 815 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信