java位是否循环变换?

我有这种使用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 << 30和16时b <32时得到0?

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

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

JLS第15.19节谈到了这一点:

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

如果左侧操作数的提升类型很长, 则只使用右侧操作数的六个最低位作为移位距离。 就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x3f(0b111111)的影响。 因此,实际使用的移位距离总是在0到63的范围内,包括0和63。

(强调我的)

(你不能对floatdouble位进行位移,并且尝试对一个short或一个byte进行位移会使值无论如何都要将一元数字提升的值赋予int 。)

16 << 30得到0 ,因为16位的1位

 00000000 00000000 00000000 00010000 

int的末尾移开并被丢弃。

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

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

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

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

 16 << 32 & 0x1f 

等于16。