注:Integer.toBinaryString()显示时,正数高位的0默认不打印,负数则会打印出符号位1。
1.左移<<
不区分正负数
左移运算符 m <<n表示把 m 左移 n 位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。
public class Test {
public static void main(String[] args) {
int i =6;
//6的二进制是110
System.out.println(Integer.toBinaryString(i));
//6向左移1位后,变成1100,对应的10进制是12
System.out.println(Integer.toBinaryString(i<<1));
System.out.println(i<<1);
int j = -2147483648;
//-2147483648的二进制是10000000000000000000000000000000
System.out.println(Integer.toBinaryString(j));
System.out.println(Integer.toBinaryString(j<<1));
System.out.println(j<<1);
}
}
运行结果:
这里第二个数 - 2147483648之所以变为0是因为:原本最左侧符号位的1(负数)被直接丢弃了,右面补0,全0。
2.带符号右移>>
区分正负数:指定值所有位向右移动指定位数。低位舍弃,高位按符号位填充。
右移运算符m>>n表示把 m 右移 n 位。在右移 n 位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要稍微复杂一点。
由于java没有无符号整数类型,数字是一个有符号数值,用数字的符号位填补最左边的位。也就是说,果数字原先是一个正数,则右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补 n 个1。
public class Test {
public static void main(String[] args) {
int i =6;
//6的二进制是110
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(i>>1));
//6向右移1位后,变成11,对应的10进制是3
System.out.println(i>>1);
int j = -2147483648;
//-2147483648的二进制是
//10000000000000000000000000000000
System.out.println(Integer.toBinaryString(j));
System.out.println(Integer.toBinaryString((j>>1)>>1));//右移两位还是负数
//11100000000000000000000000000000
System.out.println((j>>1)>>1);
//-536870912
}
运行结果:
3.无符号右移>>>
不区分正负数
指定值所有位向右移动指定位数。低位舍弃,高位补0。
这里只演示负数的情况:
public class Test {
public static void main(String[] args) {
int j = -2147483648;
//-2147483648的二进制是
//10000000000000000000000000000000
System.out.println(Integer.toBinaryString(j));
System.out.println(Integer.toBinaryString((j>>>1)>>>1));//负数变为正数
//100000000000000000000000000000 此时首位的两个0省略不显示
System.out.println((j>>>1)>>>1);
//536870912
}
运行结果:
此时无符号右移两次后,原本作为负数标志位的1被往右移了两位,不再为符号位,而变为了数值位。其左边补的0在显示的时候被省略。