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

为何Java中逻辑等价的浮点数加法结果却不一致?

问题解答:浮点数运算的精度误差问题

这不是Java的Bug,而是二进制浮点数的固有精度限制导致的必然现象。

原因分析

Java中的double类型遵循IEEE 754标准,是64位双精度浮点数。十进制小数并非都能精确转换为二进制小数——大部分十进制小数在二进制中是无限循环的近似值,存储时会被截断或舍入,导致微小的精度损失。

  • 4.3和6.26的二进制表示都是近似值,两者相加后误差累积,最终结果的二进制近似值对应的十进制数就是10.559999999999;
  • 而4.2和6.36的二进制近似值相加后,刚好能被二进制精确表示(或误差小到System.out.println输出时被自动四舍五入为10.56)。

类似的例子很常见,比如0.1 + 0.2的结果并不是精确的0.3,本质都是同一个问题。

解决办法

如果需要精确的十进制运算,或者希望输出结果符合预期,有两种常见方案:

1. 使用BigDecimal进行精确计算

java.math.BigDecimal专门用于处理高精度的十进制运算,能避免浮点数的精度损失:

import java.math.BigDecimal;

public class randomnum {
    public static void main(String[] args) {
        BigDecimal sum1 = new BigDecimal("4.3").add(new BigDecimal("6.26"));
        System.out.println(sum1); // 输出 10.56
        
        BigDecimal sum2 = new BigDecimal("4.2").add(new BigDecimal("6.36"));
        System.out.println(sum2); // 输出 10.56
    }
}

注意:创建BigDecimal时要传入字符串形式的数值,避免直接用double构造(否则会带入double本身的精度误差)。

2. 格式化输出结果

如果只是需要输出时显示正确的小数位数,可以用格式化工具截断或四舍五入:

public class randomnum {
    public static void main(String[] args) {
        double incorrectnum = 4.3 + 6.26;
        System.out.printf("%.2f%n", incorrectnum); // 输出 10.56
        
        double correctnum = 4.2 + 6.36;
        System.out.printf("%.2f%n", correctnum); // 输出 10.56
    }
}

也可以使用DecimalFormat类来定制更复杂的格式化规则。

总结

这种现象是IEEE 754浮点数的正常特性,并非语言或代码的错误。在涉及货币、精确计量等场景时,务必使用BigDecimal;普通场景下,通过格式化输出就能解决显示问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:15:41