Shift 操作符在 Java 中是如何工作的?

我正在试图了解值班员的情况,但无法获得更多信息。 当我尝试执行下面的代码时

System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));

我得到了下面

1000000000000
100000000000000000000000
100
10000000000000
1000000000000000000000000

有人能解释一下吗?

255284 次浏览

二进制十进制编号系统中的2如下

10

如果你想的话

2 << 11

就是在右边填上11个零

1000000000000

有符号的左移位操作符“ < <”将位模式向左移位,而有符号的右移位操作符“ > >”将位模式向右移位。位模式由左边的操作数给出,位移的位置数由右边的操作数给出。无符号右移操作符“ > > >”将一个零移动到最左边的位置,而“ > >”之后的最左边的位置取决于符号扩展 [..]

左移结果在术语或算术中乘以2(* 2)


例如

2在二进制 10中,如果你做 <<1那就是 100也就是 4

4在二进制 100中,如果你做 <<1,那就是 1000,也就是 8


也请看

它将通过填充那么多 0's来改变位。

对于前任,

  • 二进制 10是数字 2左移2是 1000是数字 8
  • 二进制 10是数字 2左移3是 10000是数字 16
System.out.println(Integer.toBinaryString(2 << 11));

将二进制文件2(10)向左移动11倍。因此: 1000000000000

System.out.println(Integer.toBinaryString(2 << 22));

将二进制文件2(10)向左移动22倍。因此: 100000000000000000000000

System.out.println(Integer.toBinaryString(2 << 33));

现在,int 是4个字节,因此是32位。所以当你移动33的时候,它等于移动1。因此: 100

右和左移工作在同样的方式在这里是如何右移工作; 正确的转变: 右移位操作符 > > 将一个值中的所有位向右移动指定的次数。它的一般形式是:

value >> num

在这里,num 指定将值右移的位置数。也就是说,> > 将指定值中的所有位移动到 num 指定的位位置数的右侧。 下面的代码片段将值32向右移动了两个位置,结果将值设置为8:

int a = 32;
a = a >> 2; // a now contains 8

当一个值有“移位”的位时,这些位就丢失了。例如,下一个代码片段将值35移动到正确的两个位置,这将导致两个低阶位丢失,从而再次将值设置为8。

int a = 35;
a = a >> 2; // a still contains 8

用二进制表示同样的操作,可以更清楚地看到这种情况是如何发生的:

00100011 35 >> 2
00001000 8

每次将一个值向右移动时,它都会将该值除以2ーー并丢弃所有余数。对于高性能的整数除以2,可以利用这一点。当然,您必须确保没有从正确的一端移动任何位。 当您向右移位时,由右移位暴露的顶部(最左边)位将被顶部位之前的内容填充。这就是所谓的符号扩展,用来保存负数的符号,当你把它们移到右边。例如,–8 >> 1–4,在二进制中是

11111000 –8 >>1
11111100 –4

值得注意的是,如果向右移动 -1,结果总是保持 -1,因为符号扩展不断地以高阶位引入更多的符号扩展。 有时,当您将值向右移动时,不希望对它们进行符号扩展。例如,下面的程序将字节值转换为其十六进制字符串表示形式。注意,移位后的值会被 ANDing 0x0f 屏蔽,以丢弃符号扩展位,这样该值就可以用作十六进制字符数组的索引。

// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}

下面是这个程序的输出:

b = 0xf1

我相信这个可能会有帮助:

    System.out.println(Integer.toBinaryString(2 << 0));
System.out.println(Integer.toBinaryString(2 << 1));
System.out.println(Integer.toBinaryString(2 << 2));
System.out.println(Integer.toBinaryString(2 << 3));
System.out.println(Integer.toBinaryString(2 << 4));
System.out.println(Integer.toBinaryString(2 << 5));

结果

    10
100
1000
10000
100000
1000000

编辑:

必须阅读本文(How-do-the-bitwise-shift-Operator-work)

可以使用数据类型(char、 int 和 long int)实现移位。浮点数和双数据不能移位。

value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.

我认为应该是这样的,例如:

  • 左转

[2 < < 1]是 = > [10(二进制的2)在二进制字符串末尾加10]因此10等于100就变成了4。

签名左移使用乘法..。 这也可以计算为2 * (2 ^ 1) = 4。 另一个例子[ 2 < < 11] = 2 * (2 ^ 11) = 4096

  • 右转

[4 > > 1]是 = > [100(二进制4)去掉二进制字符串末尾的1个零]因此100等于10变成2。

签署权利转移使用组织..。 这也可以计算为4/(2 ^ 1) = 2 另一个例子[ 4096 > > 11] = 4096/(2 ^ 11) = 2

左转 逻辑上来说 简单地说,如果1 < < 11,它将趋向于2048,而2 < < 11将给出4096

在 Java 编程中 Int a = 2 < < 11;

// it will result in 4096


2<<11 = 2*(2^11) = 4096

移动变量并赋值回变量的典型用法可以是 使用速记操作符 < = >>=>>>=重写,在规范中也称为 复合指配营办商

比如说,

i >>= 2

产生与... 相同的结果

i = i >> 2