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

Java中Long为何被当作32位处理?

问题分析与解决:Java位移操作的意外结果

我运行了这段Java代码:

public class MyClass { 
    public static void main(String args[]) { 
        long x = 1 << 39; 
        long l = 537150415L; 
        l = l | x; 
        System.out.println(x); 
        System.out.println(l); 
    } 
}

得到的输出是:

128 
537150415 

我原本预期x是一个很大的数值,可结果128是2^7,也就是2^(39-32),但long明明是64位的啊?我本来想实现一个能存储1-60范围内数字的位集。


问题根源:整数字面量的默认类型

你遇到的问题核心在于**1是int类型的字面量**,Java里int是32位的有符号整数。当你执行1 << 39时,这个位移操作是在int类型上进行的,而39已经超过了int的32位范围,所以会发生整数溢出,实际等价于1 << (39 % 32),也就是1 << 7,结果自然是128。

哪怕你把结果赋值给long类型变量x,位移操作本身已经在int上完成了,溢出后的结果再被转成long,所以才会得到错误的小数值。

解决方案:使用long类型的字面量进行位移

只需要把1改成1L(long类型的字面量),这样位移操作就会在64位的long上执行,不会出现溢出问题:

public class MyClass { 
    public static void main(String args[]) { 
        long x = 1L << 39; 
        long l = 537150415L; 
        l = l | x; 
        System.out.println(x); 
        System.out.println(l); 
    } 
}

现在x的值会是549755813888(也就是2^39),l也会正确地把第39位(从0开始计数)置为1,输出符合预期。

关于实现1-60范围的位集

如果是要实现存储1-60的位集,你可以继续用long类型(因为long是64位,足够覆盖1-60的位),每次设置位的时候都记得用1L << n(n是你要设置的位,注意如果是数字1对应第0位的话,要调整偏移,比如数字k对应第k-1位)。比如要设置数字10,就用1L << 9,然后和原long值做或操作即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:54:35