移位运算符在Java中是如何工作的?

移位运算符在Java中是如何工作的?,java,bit-shift,Java,Bit Shift,我正在努力理解轮班操作员,但没有得到太多。 当我试图执行下面的代码时 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.toBinaryStr

我正在努力理解轮班操作员,但没有得到太多。 当我试图执行下面的代码时

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));

有人能解释一下吗?

2二进制十进制数字系统如下

10
现在如果你这样做了

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

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


例如


2在二进制
10
中,如果执行
操作,它将通过填充那么多
0
来移动位

例如

  • 二进制
    10
    是数字
    2
    左移2是
    1000
    是数字
    8
  • 二进制
    10
    是数字
    2
    左移3是
    10000
    是数字
    16
将二进制2(
10
)向左移动22次。因此:
1000000000000000000000

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

System.out.println(Integer.toBinaryString(2Right和Left-shift以相同的方式工作这里是右移位的工作方式;
右移:
右移位运算符>>,将值中的所有位向右移位指定次数。其一般形式:

value >> num
在这里,num指定将值中的值右移的位置数。也就是说,>>将指定值中的所有位向右移动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>-1
-4
,在二进制中是

11111000 –8 >>1
11111100 –4
有趣的是,如果将–1右移,结果始终保持–1,因为符号扩展会在高阶位中不断引入更多的1。 有时,在将扩展值向右移位时,不希望对扩展值进行签名。例如,以下程序将字节值转换为其十六进制字符串表示形式。请注意,通过将移位值与0x0f进行ANDing以丢弃任何符号扩展位来屏蔽该值,以便将该值用作扩展值数组的索引十六进制字符

// 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));
编辑:


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

value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.
value=value>>步骤//右移,签名数据。

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

  • 有符号左移
[2[10(2的二进制)在二进制字符串的末尾加1零]因此10将是100,变成4

有符号左移位使用乘法。。。 所以这也可以计算为2*(2^1)=4。 另一个例子[2>1]是=>[100(4的二进制)在二进制字符串的末尾删除1个零],因此100将是10,变成2

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

符号左移 逻辑上
简单如果1将变量移位并重新分配给变量的典型用法可以是 使用速记运算符重写,在规范中也称为

比如说,

i >>= 2
产生与相同的结果

i = i >> 2

左移位等于乘以2,而右移位等于整数除以2。也许值得强调的是,“二进制形式的2是…”你一定更喜欢循环。是的。事实上,我只是想保持简单易懂。Java定义了移位以屏蔽(环绕)倒计时到0-31范围,而不是饱和到32(如果移位32只左零)。(显然,使用32位类型)我假设做出此决定是为了匹配x86移位和旋转指令的行为。相比之下,在C中,按
count>=类型宽度
移位是未定义的行为。(有关在C中编写安全旋转所需的解决方法,请参阅。)但是它的用途是什么?就像我现在看不到使用位的用途,除非你喜欢使用机器语言或其他正确的东西一样?@carinlynchin移位操作对整数进行幂运算很有用(
Math.Pow())
接收并返回一个
double
。有时,移位比将
int
转换为
double
、调用
Math.pow()
并转换回
int
)更短/更有效。它还可用于将
int
值从有符号(Java)转换为无符号等效值(C/C++;Java没有无符号类型,这是它的缺点之一)。
    10
    100
    1000
    10000
    100000
    1000000
value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.
// it will result in 4096

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