轮班操作员如何在Java中工作?

How do shift operators work in Java?

本问题已经有最佳答案,请猛点这里访问。

我试着去了解值班长,但没什么收获。当我试图执行以下代码时

1
2
3
4
5
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));

我得到下面

1
2
3
4
5
1000000000000    
100000000000000000000000    
100    
10000000000000    
1000000000000000000000000

有人能解释一下吗?


1
System.out.println(Integer.toBinaryString(2 << 11));

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

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

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

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

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


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

1
10

现在如果你这样做

1
2 << 11

在右边加上11个零

1
1000000000000

The signed left shift operator"<<" shifts a bit pattern to the left, and the signed right shift operator">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator">>>" shifts a zero into the leftmost position, while the leftmost position after">>" depends on sign extension [..]

左移位导致术语或算术乘2(*2)

例如

2在二进制10中,如果您执行<<1操作,则会是100操作,即4操作。

4在二进制100中,如果您执行<<1操作,那么将是1000,即8

也看到

  • 绝对初学者钻头移动指南


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

1
value >> num

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

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

当一个值有"移位"的位时,这些位就会丢失。例如,下一个代码片段将值35移到右边的两个位置,这会导致两个低阶位丢失,从而再次导致设置为8。

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

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

1
2
00100011 35 >> 2
00001000 8

每次将值右移时,它都会将该值除以2,并丢弃任何余数。您可以利用这一点进行高性能整数除以2。当然,你必须确保你没有从右端移动任何比特。当您右移时,右移所显示的最上面(最左边)位将用最上面的位的先前内容填充。这被称为符号扩展,用于在将负数右移时保留它们的符号。例如,–8 >> 1–4,二进制表示

1
2
111110008 >>1
111111004

有趣的是,如果向右移动-1,结果始终保持-1,因为符号扩展会不断引入更多的高阶位。有时,当您将值右移时,不希望对扩展值进行签名。例如,以下程序将字节值转换为十六进制字符串表示形式。请注意,移位的值被用0x0F对其进行了加运算,以放弃任何符号扩展位,以便该值可以用作十六进制字符数组的索引。

1
2
3
4
5
6
7
8
9
10
11
// 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]);
}
}

下面是这个程序的输出:

1
b = 0xf1

我相信这可能有助于:

1
2
3
4
5
6
    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));

结果

1
2
3
4
5
6
    10
    100
    1000
    10000
    100000
    1000000

编辑:

必须阅读此内容(位移位运算符如何工作)


例如,我认为应该是:

  • 有符号的左移位

[2<<1]is=>[10(binary of 2)add 1 zero at the end of the binary string]so 10 will be 100 which变为4.

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

  • 有符号右移

[4>>1]is=>[100(二进制4)在二进制字符串的末尾删除1零],因此100将是10,变为2。

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


移位可以用数据类型(char、int和long int)实现。浮点和双精度数据意味着要移位。

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


它将通过填充多个0's来移动位。

对于EX,

  • 二元10是数字2左移2,是数字1000是数字8
  • 二元10是数字2左移3,是数字10000是数字16

有符号的左移位逻辑上简单来说,如果1<<11,它将趋向于2048,而2<<11将得到4096。

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

1
2
3
// it will result in 4096

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

移动变量并重新分配给变量的典型用法可以是使用速记运算符<<=、>>=或>>=重写,在规范中也称为复合赋值运算符。

例如,

1
i >>= 2

产生的结果与

1
i = i >> 2