You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Double类型相除取整数部分异常原因及最优解法

误差产生的原因

这个问题本质是浮点数精度丢失导致的:

  • Java中double类型基于IEEE 754二进制浮点数标准实现,绝大多数十进制小数都无法被精确存储为二进制浮点数,你代码里的18.2和2.6转成Double对象时本身就带有微小的精度误差
  • 两个本身有误差的浮点数做除法后误差会进一步累积,最终计算结果不是精确的7.0,而是接近7的6.99999...这类值,调用intValue()时会直接截断小数部分,所以得到6而非预期的7。

现有DecimalFormat方案的说明

你目前用的DecimalFormat方案能得到正确结果,但算不上最优方案,存在几个明显问题:

  • 性能开销过大:DecimalFormat是重量级格式化类,实例化和格式化操作都有额外开销,单纯为了取整使用属于大材小用
  • 规则隐式不透明:不显式指定舍入模式的话,会用默认的RoundingMode.HALF_EVEN,后续需求调整舍入规则时容易出隐藏问题
  • 输出结果为字符串类型,如果后续还要对结果做数值运算,需要额外做类型转换,非常不方便。

更合适的实现方式

根据不同的使用场景,推荐两种更优的方案:

场景1:精度要求不高,追求代码极简

直接用Math.round()对运算结果做四舍五入后取整即可,代码比DecimalFormat轻量很多,输出直接是数值类型:

Double price = new Double("18.2");
Double qte = new Double("2.6");
double res = price / qte;
// 输出7,结果为long类型
System.out.println(Math.round(res));

场景2:精度要求极高(比如涉及金额、计量类计算)

完全避免用double/float做数值运算,统一用BigDecimal处理,从根源杜绝精度丢失,还可以显式指定舍入规则,可控性最高:

import java.math.BigDecimal;
import java.math.RoundingMode;

// 直接用字符串构造BigDecimal,避免中间转double的精度损失
BigDecimal price = new BigDecimal("18.2");
BigDecimal qte = new BigDecimal("2.6");
// 除法时指定保留0位小数,舍入模式用四舍五入(可根据需求更换其他舍入模式)
BigDecimal res = price.divide(qte, 0, RoundingMode.HALF_UP);
// 输出7,结果为整数类型
System.out.println(res.intValue());

内容的提问来源于stack exchange,提问作者user2178964

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:42:01