<<左移运算符
>>有符号右移
>>>无符号右移
***位运算符都是使用二进制补码进行运算
int num1 = 8;//正数的原码、补码、反码相同,直接转换成二进制,如下:
0000 0000 0000 0000 0000 0000 0000 1000 原码
0000 0000 0000 0000 0000 0000 0000 1000 反码
0000 0000 0000 0000 0000 0000 0000 1000 补码
int num2 = -6;、
//负数的原码,在相反数的原码前加上符号位,即高位改成1,
//负数的反码,由原码除符号位全部取反得到,1变0,0变1
//负数的补码,由反码+1得到
1000 0000 0000 0000 0000 0000 0000 0110 原码
1111 1111 1111 1111 1111 1111 1111 1001 反码
1111 1111 1111 1111 1111 1111 1111 1010 补码
public class Test_01 {
public static void main(String[] args) {
一、正数的 << >> >>>
1、正数的<<有符号左移
int c1 = 3;
c1 = c1 << 3;
//0000 0000 0000 0000 0000 0000 0000 0011 正数原码、反码、补码相同
//0000 0000 0000 0000 0000 0000 0001 1000 正数直接左移3位,低位补0
System.out.println("c1 = " + c1);//c1 = 24
2、正数的>>有符号右移
int c2 = 3;
c2 = c2 >> 1;
//0000 0000 0000 0000 0000 0000 0000 0011 补码
//0000 0000 0000 0000 0000 0000 0000 0001 正数直接右移1位,高位补0
System.out.println("c2 = " + c2);//c2 = 1
3、正数的>>>无符号右移
正数无符号右移与有符号右移一样
二、负数的 << >> >>>
1、负数的<<有符号左移
int a1 = -5;
a1 = a1 << 2;
//1000 0000 0000 0000 0000 0000 0000 0101 -5的原码
//1111 1111 1111 1111 1111 1111 1111 1010 -5的反码
//1111 1111 1111 1111 1111 1111 1111 1011 -5的补码
//1111 1111 1111 1111 1111 1111 1110 1100 负数左移2位,低位补0
此处为补码,要得到结果转换成原码(负数)
//1111 1111 1111 1111 1111 1111 1110 1011 补码-1得到反码
//1000 0000 0000 0000 0000 0000 0001 0100 反码 (除符号位) 取反得到原码
System.out.println("a1 = " + a1);//a1 = -20
2、负数的>>有符号右移
int a2 = -5;
a2 = a2 >> 2;
//1111 1111 1111 1111 1111 1111 1111 1011 -5补码
//1111 1111 1111 1111 1111 1111 1111 1100 负数右移2位,高位补1
//1111 1111 1111 1111 1111 1111 1111 1101 +1
//1000 0000 0000 0000 0000 0000 0000 0010 取反
System.out.println("a2 = " + a2);//a2 = -2
3、负数的>>>无符号右移
int a3 = -2;
a3 = a3 >>> 1;
//1111 1111 1111 1111 1111 1111 1111 1110 -2补码
//0111 1111 1111 1111 1111 1111 1111 1111 无符号右移1位,高位补0
System.out.println("a3 = " + a3);//a3 = 2147483647
}
}
m >> n : 将m转换成二进制,然后向右移动n位
如果m是正数,则前面补n个0
如果m是负数,则前面补n个1
m << n : 将m转换成二进制,然后向左移动n位,不分正负,后面补n个0
m >>> n: 将m转换成二进制,然后向右移动n位,不分正负,前面补n个0