java比特移位循环吗?

时间:2014-02-10 18:59:50

标签: java bit-manipulation bit-shift

我使用Java有这种行为:

int b=16;
System.out.println(b<<30);
System.out.println(b<<31);
System.out.println(b<<32);
System.out.println(b<<33);

输出: 0 0 16 32

java位移位是否循环?如果不是,为什么我在b <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

2 个答案:

答案 0 :(得分:12)

位移不是循环的;对于位移int,Java仅使用5个最低有效位,因此(b << 0)等同于(b << 32)(相当于(b << 64)等)。您可以简单地取位移量并在除以32时取余数。

对于位移long s类似的情况,其中Java仅使用6个最低有效位,因此(aLong << 0)等同于(aLong << 64)

Section 15.19 of the JLS谈到这个:

  

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

     

如果左侧操作数的提升类型为long,则右侧操作数的仅六个最低位用作移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移位距离始终在0到63之间,包括0和63.

(强调我的)

(您无法对floatdouble进行位移,尝试对shortbyte进行位移将使值为无论如何,一元数字促销int。)

您从0获得16 << 30,因为来自16的1位

00000000 00000000 00000000 00010000

int的末尾移开并被丢弃。

// Discarded - Result-----------------------------
  (00000100)   00000000 00000000 00000000 00000000 

答案 1 :(得分:5)

不,这不是循环转变。这是正常的左移。只是,对于int类型左侧操作数,Java仅使用右操作数的5个低位进行移位。这是按JLS §15.9

  

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

因此,对于16 << 32,仅考虑32的5个低阶位,表达式相当于:

16 << 32 & 0x1f

等于16。