>>>和比;比;

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

261483 次浏览

它们都是右移,但是>>>unsigned

文档:

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

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

>>是算术右移,>>>是逻辑右移。

在算术移位中,符号位被扩展以保持数字的有号性。

例如:用8位表示的-2将是11111110(因为最高有效位的权值为负)。使用算术移位向右移动一位将得到11111111,或-1。然而,逻辑右移并不关心该值是否可能表示有符号的数字;它只是把所有东西都移到右边,然后从左边填上0。使用逻辑移位将-2右移一位将得到01111111

>>>是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。

相关问题

阅读更多关于位移位和位移位操作符

>>      Signed right shift
>>>     Unsigned right shift

位模式由左操作数给出,而右操作数要移位的位置数。无符号右移操作符>>> 0 移到最左边的位置

>>之后最左边的位置取决于符号扩展。

简单地说,>>>总是 0 移到最左边的位置,而>>基于数字的符号移位,即1表示负数,0表示正数。


例如,尝试用负数和正数。

int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));


System.out.println();


c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));

输出:

11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100


100110
10011000
100110
10011000

右移逻辑运算符(>>> N)将位右移N位,丢弃符号位,并用0填充最左边的N位。例如:

-1 (in 32-bit): 11111111111111111111111111111111

>>> 1操作之后变成:

2147483647: 01111111111111111111111111111111

右移算术运算符(>> N)也将位右移N位,但保留符号位,并将最左边的N位填充为1。例如:

-2 (in 32-bit): 11111111111111111111111111111110

>> 1操作之后变成:

-1: 11111111111111111111111111111111

逻辑右移(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的幂必须保持符号不变。

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

在祝辞(签名)将给你不同的结果8 >>2、-8 >>2.

右移8

8 = 1000(二进制)

执行2位右移

8在祝辞2:

1000年在祝辞2 = 0010(相当于2)

右移-8

8 = 1000(二进制)

1的补码= 0111

2的补充:

0111 + 1 = 1000

符号位= 1

执行2位右移(对2的co结果)

8在祝辞2:

1000年在祝辞2 = 1110(相当于-2)


在祝辞(无符号)将给你同样的结果8 >>>2、-8 >>>2.

8的无符号右移

8 = 1000

8在祝辞祝辞2 = 0010

无符号右移-8

-8 = 1000

8在祝辞祝辞2 = 0010