JAVA移位运算符>>和>>>

JAVA的移位运算符有三种:

<<      :     左移运算符,右端补零

>>      :     右移运算符,左端补符号位

>>>    :     无符号右移,左端补零

注意:

>>和>>>只对负数有区别, 因为整数符号位是0

并没有<<<运算符,因为左移时右端补零和<<一样

>>叫算术位移,左侧补符号位, >>>叫逻辑位移, 左侧补0

位移操作数字的补码, 因为计算机内以补码形式存储数字

>>,<<移位时不影响符号位 ,>>>移位影响符号位

int a=2;
System.out.println(a>>1);
System.out.println(a>>>1);

//结果是两个1 
//说明对于正数>> 和 >>> 一样
		int a=-1;
		System.out.println(a>>1);
		System.out.println(a>>>1);
//第一个输出:-1
//第二个输出:2147483647

可以看到上例int型的 -1  原码 是  1  00000000 00000000 00000000 0000001

如果是原码移位的话  -1>>1 后应该是  1  10000000 00000000 00000000 0000000=1073741824

原码-1>>>1 后应该时 1  00000000 00000000 00000000 0000000=-0

与输出不符,显然移位的并不是数字的原码而是补码:

原码 补码 操作 结果
-1 1  00000000 00000000 00000000 0000001 1 11111111 11111111  11111111 1111111 >> 1 11111111 11111111  11111111 1111111(这是补码) = -1
-1 1  00000000 00000000 00000000 0000001 1 11111111 11111111  11111111 1111111 >>> 0 11111111 11111111  11111111 1111111(这是原码)=2147483647

也就是说:

JAVA所有移位运算符直接操作补码
<<和>>运算符 不影响符号位, 从符号位后移位开始移位, >>左端补符号位 ,移位后把补码转换成原码输出

>>> 无视符号位(故而叫逻辑右移),  不分正负,把存储的数当作原码处理(即使存储是补码)符号为也会右移, 左端补零

再举个例子:

	public static void main(String[] args)
	{
		int a=-1;
		int b=-999;
		int c=1;
		int d=999;
		System.out.println(a>>31);
		System.out.println(b>>31);
		System.out.println(c>>31);
		System.out.println(d>>31);
	}
//输出:
//-1
//-1
//0
//0

移位31位后数的补码只剩下 32位符号位全1 或全零 转回原码则是 -1 和0

因而>>31或者大于31时 原来是正数则等于0 负数则等于-1, 只与正负有关,与大小无关

这样可以达到判断正负的目的, 类似的也可以用>>>达到目的,如下例

	public static void main(String[] args)
	{
		int a=-1;
		int b=-999;
		int c=1;
		int d=999;
		System.out.println(a>>>31);
		System.out.println(b>>>31);
		System.out.println(c>>>31);
		System.out.println(d>>>31);
	}
//输出:
//1
//1
//0
//0

逻辑右移>>>31位时把符号位移到了最后, 输出也就是1或0   与大小无关

可以这样判断符号位是正是负,  是否位0

猜你喜欢

转载自blog.csdn.net/q5706503/article/details/82950996