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

int溢出场景下使用1与1.0运算后转换为double的结果差异疑问

int溢出场景下使用1与1.0运算后转换为double的结果差异疑问

先来看你的代码和输出:

public class foo {
    public static void main(String [] args){
        int a = (int) Math.pow(2, 30);
        double d = (a + a - 1.0);
        double f = (a + a - 1);
        System.out.println(d);
        System.out.println(f);
    }
}

输出结果:

-2.147483649E9
2.147483647E9

你的疑惑我完全理解,一开始碰到这种情况确实容易懵,咱们一步步拆解问题的核心:

首先明确几个关键前提:

  • a的值是2^30也就是1073741824,这个值在int的范围内(int最大值是2^31-1=2147483647),没问题。
  • a+a等于2147483648,这已经超过了int的最大值,触发整数溢出,按照Java的补码规则,这个值会变成int的最小值:-2147483648。

现在分别看两个表达式的运算逻辑:

第一个表达式:a + a - 1.0

这里运算时遇到了1.0这个double类型的值,Java会先把前面溢出后的int结果(-2147483648)转换成double类型(也就是-2147483648.0),然后再做减法:-2147483648.0 - 1.0 = -2147483649.0,也就是你看到的-2.147483649E9。

第二个表达式:a + a - 1

这里的所有运算都是int类型的!第一步a+a溢出得到-2147483648,接下来用这个值减1(int类型),这时候又触发了一次溢出——因为-2147483648是int能表示的最小值,再减1的话,补码运算会让它循环到int的最大值:2147483647。最后把这个int值转换成double,就得到了2147483647.0,也就是输出的2.147483647E9。

简单总结一下:

  • 第一个表达式因为有double参与,提前把溢出后的int转成了double,后续减法是double运算,不会再溢出;
  • 第二个表达式全程都是int运算,溢出后再减1又一次溢出,结果变成了int的最大值,最后才转成double。

备注:内容来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 14:42:32