0

考虑以下代码。

  1. 1 >> 34 = 0,
  2. 1 << 34 = 4 // 循环移位

为什么会出现这种不对称?

4

3 回答 3

5

JLS §15.19

如果左侧操作数的提升类型是 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 个最低位来计算。这不是循环移位操作。他们都不是。这就是他们的行为方式。

于 2013-10-14T11:47:26.677 回答
2

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
于 2013-10-14T11:47:50.060 回答
0

当使用带符号的移位运算符右移时1>>34,按照oracle 文档,左边用符号填充,在这种情况下,1 为正,符号为 0。第一次移位时丢失1>>1 = 0

当使用带符号的移位运算符左移时,1<<34会发生以下情况:

0x0001<<34 = (0x0001 << 32) << 2 = 0x0004 = 4
于 2013-10-14T11:47:17.960 回答