154

我试图了解轮班操作员,但没有得到太多。当我尝试执行以下代码时

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    

有人可以解释一下吗?

4

9 回答 9

220
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

于 2012-06-06T08:48:30.617 回答
42

2 来自十进制的二进制数字系统如下

10

现在如果你这样做

2 << 11

会是,11个零将被填充在右侧

1000000000000

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

左移导致在术语或算术上乘以 2 (*2)


例如

2 in binary 10,如果你这样做<<1,那将1004

4 二进制100,如果你这样做 <<11000那就是8


另见

于 2012-06-06T08:46:22.480 回答
16

右移和左移的工作方式相同,这里是右移的工作原理;右移:右移运算符 >> 将值中的所有位向右移动指定的次数。它的一般形式:

value >> num

此处,num 指定将 value 中的值右移的位置数。也就是说,>> 将指定值中的所有位向右移动 num 指定的位数。以下代码片段将值 32 向右移动两个位置,从而将 a 设置为 8:

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

当一个值具有“移出”的位时,这些位将丢失。例如,下一个代码片段将值 35 向右移动两个位置,这导致两个低位丢失,导致 a 再次被设置为 8。

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

查看二进制中的相同操作可以更清楚地显示这是如何发生的:

00100011 35 >> 2
00001000 8

每次将一个值向右移动时,它都会将该值除以 2,并丢弃任何余数。您可以利用这一点进行高性能整数除以 2。当然,您必须确保没有将任何位移出右端。当您右移时,右移所暴露的最高(最左)位将用最高位的先前内容填充。这称为符号扩展,用于在您向右移动负数时保留负数的符号。例如,–8 >> 1is –4,在二进制中,是

11111000 –8 >>1
11111100 –4

有趣的是,如果将 –1 右移,结果始终保持为 –1,因为符号扩展不断在高位中引入更多的位。有时,当您将它们向右移动时,不希望对值进行符号扩展。例如,以下程序将字节值转换为其十六进制字符串表示形式。请注意,移位的值通过与 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
于 2013-04-10T23:20:31.547 回答
13

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

    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

编辑:

必读(按位移位运算符如何工作)

于 2014-09-10T03:54:31.540 回答
8

我想应该是这样的,例如:

  • 签名左移

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

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

  • 有符号右移

[ 4 >> 1 ] is => [100 (binary of 4) remove 1 zero at the end of the binary string] 因此 100 将是 10 变成 2。

有符号右移使用除法...所以这也可以计算为 4 / (2^1) = 2 另一个例子 [ 4096 >> 11] = 4096 / (2^11) = 2

于 2015-03-10T12:22:59.093 回答
4

它将通过填充那么多0's.

例如,

  • 二进制10 是数字2左移 21000是数字8
  • 二进制10 是数字2左移 310000是数字16
于 2012-06-06T08:47:18.477 回答
2

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

value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.
于 2015-02-26T21:15:55.503 回答
2

带符号的左移 逻辑上简单,如果 1<<11 它将趋于 2048 并且 2<<11 将给出 4096

在java编程中 int a = 2 << 11;

// it will result in 4096

2<<11 = 2*(2^11) = 4096
于 2018-06-18T10:13:00.453 回答
1

移位变量和赋值回变量的典型用法可以用速记运算符<<=>>=>>>=重写,在规范中也称为复合赋值运算符

例如,

i >>= 2

产生与

i = i >> 2
于 2018-08-15T23:20:58.463 回答