Java奇异程序输出中的Shift运算符

时间:2011-03-05 07:07:10

标签: java

我遇到了以下程序,并且表现得出乎意料。

public class ShiftProgram
{
      public static void main(String[] args)
      {
             int i = 0;
             while(-1 << i != 0)
                   i++;
             System.out.println(i);
      }
}

如果我们考虑这个程序输出,当它达到32时,循环条件应该返回false并终止,它应该打印32。

如果您运行此程序,它不会打印任何内容,但会进入无限循环。有什么想法吗?先感谢您。

2 个答案:

答案 0 :(得分:6)

移位计数的解释模数为int(32)中的位数,因此i << 32仅为i << 0,即i。因此,您永远不会得到0作为结果。我的来源是http://www.janeg.ca/scjp/oper/shift.html。如果您执行int n = -1; while (n != 0) {i++; n <<= 1;}之类的操作,它最终会按照您的意愿到达0

答案 1 :(得分:6)

您是否尝试在循环中打印(-1 << i)以查看出现了什么问题?如果你这样做,你会看到它:

-1 << 0 = -1
-1 << 1 = -2
-1 << 2 = -4
-1 << 3 = -8
-1 << 4 = -16
-1 << 5 = -32
-1 << 6 = -64
-1 << 7 = -128
-1 << 8 = -256
-1 << 9 = -512
-1 << 10 = -1024
-1 << 11 = -2048
-1 << 12 = -4096
-1 << 13 = -8192
-1 << 14 = -16384
-1 << 15 = -32768
-1 << 16 = -65536
-1 << 17 = -131072
-1 << 18 = -262144
-1 << 19 = -524288
-1 << 20 = -1048576
-1 << 21 = -2097152
-1 << 22 = -4194304
-1 << 23 = -8388608
-1 << 24 = -16777216
-1 << 25 = -33554432
-1 << 26 = -67108864
-1 << 27 = -134217728
-1 << 28 = -268435456
-1 << 29 = -536870912
-1 << 30 = -1073741824
-1 << 31 = -2147483648
-1 << 32 = -1
-1 << 33 = -2
-1 << 34 = -4
-1 << 35 = -8
-1 << 36 = -16
[.. etc ..]

根据language specification

  

n&lt;&lt; s的值是n个左移位的位位置;这相当于(即使发生溢出)将2乘以幂s。

...所以结果总是保持负面。

该文件还告诉您:

  

如果左侧操作数的提升类型为int,则只使用右侧操作数的五个最低位作为移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (§15.22.1),掩码值为0x1f。因此,实际使用的移动距离始终在0到31的范围内,包括0和31。

因此,如果您使用32的转变,则将其解释为32 & 0x1f的转变,即0。移至-1的{​​{1}}仍为0,而非-1