>>>和>>之间的区别
Java中的运算符>>>
和>>
什么区别?
>>
是算术右移, >>>
是逻辑右移。
在算术移位中,符号位被扩展以保持数字的符号性。
例如:以8位表示的-2将是11111110
(因为最高有效位具有负权重)。 使用算术转换将其右移一位会给你11111111
或-1。 然而,逻辑右移并不在乎价值可能代表一个数字; 它只是将所有东西都移动到右边,并用0填充。 我们-2右移一位使用逻辑移位将给01111111
。
>>>
是无符号移位; 它会插入0. >>
被签名,并将扩展符号位。
JLS 15.19移位操作符
移位运算符包括左移
<<
,右移符号>>
和无符号右移>>>
。
n>>s
的值是n
个具有符号扩展的右移位位置。
n>>>s
的值是具有零扩展的n
右移位位置。
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。
相关问题
- 右移以2开-1执行分割
- 在Java中乘法和除法比移位更快吗? 。净?
- 什么是C / C ++等效的方式做'>>>'在Java(无符号右移)
- 消极的逻辑转移
- Java的>>与>>>操作符?
- Java运算符>>和>>>有什么区别?
- >>>和>>运算符之间的区别
- 像C#/ Java这样的高级语言屏蔽位移计数操作数的原因是什么?
-
1 >>> 32 == 1
-
它们都是右移,但是>>>
是unsigned
从文档 :
无符号右移运算符“>>>”将零移动到最左边的位置,而“>>”之后的最左边位置取决于符号的扩展。
>>>
总是在最左边放一个0,而>>
会根据它的符号放置一个1或一个0。
逻辑右移( v >>> n
)返回一个值,其中v
中的位向右移动了n
位,0从左侧移入。 考虑移动8位值,用二进制编写:
01111111 >>> 2 = 00011111 10000000 >>> 2 = 00100000
如果我们把这些位解释为一个无符号的非负整数,逻辑右移就会将这个数除以相应的2的幂。但是,如果这个数是二进制补码表示,那么逻辑右移就不能正确地把负数分开。 例如,当位被解释为无符号数时,上面的第二个右移位移到128到32。 但是,正如在Java中所典型的那样,这个位被解释为二进制补码。
因此,如果你正在移动以便用二的幂来除法,那么你需要算术右移( v >> n
)。 它返回一个值,其中v
中的位已经向右移动了n
位,并且v的最左边的位的拷贝从左侧移入:
01111111 >> 2 = 00011111 10000000 >> 2 = 11100000
当位是二进制补码表示中的数字时,算术右移具有除以2的幂的效果。 这是有效的,因为最左边的位是符号位。 用两个幂来划分必须保持符号相同。
了解更多关于按位和位移操作符的信息
>> Signed right shift >>> Unsigned right shift
位模式由左侧操作数给出,位数由右侧操作数进行移位。 无符号的右移运算符>>>
将零移到最左边的位置 ,
而>>
之后的最左边的位置取决于符号的扩展。
简单地说>>>
总是将零移动到最左边的位置,而>>
基于数字的符号移动,例如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个位置,但保留符号位并用1填充N个最左边的位。 例如:
-2 (in 32-bit): 11111111111111111111111111111110
>> 1
操作后:
-1: 11111111111111111111111111111111