考虑以下代码。
- 1 >> 34 = 0,
- 1 << 34 = 4 // 循环移位
为什么会出现这种不对称?
如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数经过位逻辑与运算符 & (§15.22.1) 与掩码值0x1f (0b11111)。因此,实际使用的移动距离总是在 0 到 31 的范围内,包括 0 到 31。
所以,这不是<<
循环的,>>
也不是。正是你选择的价值,让你相信了这一点。
1
通过移位34
,考虑最低 5 位:
1 >> 34 === 1 >> 2 === 0
1 << 34 === 1 << 2 === 4
由于34 & 0x1F == 2
.
现在,取一些更大的值,从技术上讲,位移2
不会让你得到0
:
4 >> 34 == 4 >> 2 == 1
4 << 34 == 4 << 34 == 16
类型的移位距离int
始终使用 5 个最低位来计算。这不是循环移位操作。他们都不是。这就是他们的行为方式。
Shift 只对 int 使用低 5 位,对 long 使用低 6 位。
1 >> 34 = 0
这与 1 >> 2 相同,即 0,因为这不是圆形旋转。
1 << 34 = 4 // 循环移位
这与 1 << 2 相同,因为移位仅将低 5 位用于 int,将低 6 位用于 long。
这不是循环移位。
例如
Integer.MIN_VALUE << 1 // is 0
当使用带符号的移位运算符右移时1>>34
,按照oracle 文档,左边用符号填充,在这种情况下,1 为正,符号为 0。第一次移位时丢失1>>1 = 0
当使用带符号的移位运算符左移时,1<<34
会发生以下情况:
0x0001<<34 = (0x0001 << 32) << 2 = 0x0004 = 4