Java中的>>>和>>操作符有什么区别?


当前回答

>>>总是在最左边放一个0,而>>会放一个1或0,这取决于它的符号是什么。

其他回答

>>>总是在最左边放一个0,而>>会放一个1或0,这取决于它的符号是什么。

逻辑右移(v >>> n)返回一个值,其中v中的位向右移动了n位,0从左侧移动。考虑移位8位的值,用二进制写:

01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000

如果我们将位解释为无符号非负整数,逻辑右移的效果是将该数字除以相应的2次方。然而,如果数字是二补表示,逻辑右移不能正确地除负数。例如,当比特被解释为无符号数字时,上面的第二个右移将128移到32。但是,当二进制位被解释为二进制补位时(这在Java中很典型),它会将-128转换为32。

因此,如果你为了除以2的幂而移动,你需要算术右移(v >> n)。它返回一个值,其中v中的位向右移动了n位,并且v中最左边的位的副本从左边移动:

01111111 >> 2 = 00011111
10000000 >> 2 = 11100000

当二进制位是二补表示的数字时,算术右移的效果是除以2的幂。这是因为最左边的位是符号位。除以2的幂必须保持符号不变。

>>>是unsigned-shift;它会插入0。>>是有符号的,将扩展符号位。

JLS 15.19 Shift运算符

移位操作符包括左移位<<,有符号右移位>>,无符号右移位>>>。 n>>s的值是带符号扩展的n个右移s位。 n>>>s的值是n个右移s位,扩展为零。

    System.out.println(Integer.toBinaryString(-1));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >> 16));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >>> 16));
    // prints "1111111111111111"

为了让事情更清楚,加上正面对应

System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"

因为它是正的,有符号和无符号移位都会在最左边加0。

相关问题

右移执行在-1上除以2 在Java中移位比特比乘除快吗?net ? c/c++在Java中' >>> '的等效方式是什么(无符号右移) 负逻辑位移 Java的>> vs >>>操作员? Java操作符>>和>>>有什么区别? >>>和>>操作符的区别 为什么像c# /Java这样的高级语言会屏蔽位移位计数操作数? 1 >>> 32 == 1

>>  Signed right shift 
>>> Unsigned right shift

例子:-

byte x, y;  x=10;  y=-10;  
SOP("Bitwise Left Shift: x<<2 = "+(x<<2));  
SOP("Bitwise Right Shift: x>>2 = "+(x>>2));  
SOP("Bitwise Zero Fill Right Shift: x>>>2 = "+(x>>>2));  
SOP("Bitwise Zero Fill Right Shift: y>>>2 = "+(y>>>2));

输出将是:-

Bitwise Left Shift: x<<2 = 40
Bitwise Right Shift: x>>2 = 2
Bitwise Zero Fill Right Shift: x>>>2 = 2
Bitwise Zero Fill Right Shift: y>>>2 = 1073741821

它们都是右移,但是>>>是无符号的

从文档中可以看到:

无符号右移运算符“>>>”将0移到最左边的位置,而“>>”之后的最左边位置取决于符号扩展。