位移运算问题

小白
  • 40
        System.out.println(Long.toBinaryString((-1)<<32));
        System.out.println(Long.toBinaryString((-1L)<<32));

结果分别是

1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111100000000000000000000000000000000

第二个输出倒是在预料之内,主要是不明白第一个的输出,为什么结果和第二个输出不一样?
我隐约感觉应该是第一个算出来的类型是int类型,所以导致了这个问题。
但更深层次的,就想不到了

回复
阅读 1.6k
1 个回答
BattleHeart
  • 701
✓ 已被采纳
  1. int类型位移的是0-31,int类型长度最小值是-2,147,483,648(-2^31,最大值是2,147,485,647(2^31 - 1);向左移动高位移除,低位补0
  2. long类型位移的范围是0-63,最小值是-9,223,372,036,854,775,808(-2^63),最大值是9,223,372,036,854,775,807(2^63 -1),向左移动高位移除,低位补0
  3. 如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对(第一种方式)int型移动32位,已经超过的int的最大位数31,所以需要对32进行取模操作,实际上只移动了32取模于2=0位。

也就是当int指定向左移动32位时,已经超过了范围所以会对32进行取模操作,希望对你有帮助,如果能帮到您希望能够采纳。
举例来说明这个问题:

System.out.println(Long.toBinaryString((-1)<<33));
System.out.println(Long.toBinaryString((-1L)<<32));

我先来解读下这两段代码的区别点在于前期我们位移的时候的元素,第一个位移的元素是int类型,第二个位移的元素是long类型,前面已经说到int的位移0-31位,long的位移是0-63位,第一个int移动了33位已经超出了该类型的最大位数,则会对指定位移的33位取模操作,取模底数为2,最后计算得出结果是1位。

1111111111111111111111111111111111111111111111111111111111111110
1111111111111111111111111111111100000000000000000000000000000000

输出结果也是移动了1位,为什么前面是int类型的长度会这么长,因为你转成了long类型,我有对该内容进行了补充,如果又不懂得请留言。

宣传栏