1、描述
- 计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算称为位运算,而我们看到的十进制数,则是计算机通过二进制运算之后转为了十进制转换的结果。
- 下面代码示例中会在变量后面注释二进制形式,以Java的int类型计算,int类型长度为4字节,总共32位,第一位为符号位,1为负数,0为正数,如1的二进制即为0000 0000 0000 0000 0000 0000 0000 0001,-1则为1000 0000 0000 0000 0000 0000 0000 0001,为了方便演示,会取一些各位数为变量的值,所以中间的0省略,正数写成0...0001,负数写成1...0001。
- 二级制运算中,是通过补码运算,正数的补码=反码=原码,负数的补码=原码取反 + 1,计算结果如果是符号位是0,则直接转换十进制,为1则先求补码,再转为十进制。负数参与计算一样。
2、"&" 与运算(两个位都为1则为1)
public static void example1() {
int i1 = 1; //0 ... 0001
int i2 = 0; //0 ... 0000
int i3 = 1; //0 ... 0001
/** 二进制 十进制
* 0 ... 0001 1 0 ... 0001 1
* & &
* 0 ... 0000 0 0 ... 0001 1
* ___________________________________________________________
* 0 ... 0000 0 0 ... 0001 1
**/
System.out.println("i1 & i2 =" + (i1 & i2));
System.out.println("i1 & i3 =" + (i1 & i3));
}
//结果:
i1 & i2 = 0
i1 & i3 = 1
3、"|" 或运算(一个为1则为1)
public static void example1() {
int i1 = 1; //0 ... 0001
int i2 = 0; //0 ... 0000
int i3 = 1; //0 ... 0001
/** 二进制 十进制
* 0 ... 0001 1 0 ... 0001 1
* & &
* 0 ... 0000 0 0 ... 0001 1
* ___________________________________________________________
* 0 ... 0000 0 0 ... 0001 1
**/
System.out.println("i1 & i2 = " + (i1 & i2));
System.out.println("i1 & i3 = " + (i1 & i3));
}
//结果:
i1 | i2 = 1
i1 | i3 = 1
4、"^" 异或运算(两个不同则为1)
public static void example3() {
int i1 = 1; //0001
int i2 = 2; //0010
int i3 = 3; //0011
/** 二进制 十进制
* 0 ... 0001 1 0 ... 0001 1
* & &
* 0 ... 0010 2 0 ... 0011 3
* ___________________________________________________________
* 0 ... 0011 3 0 ... 0010 2
**/
System.out.println("i1 ^ i2 =" + (i1 ^ i2));
System.out.println("i1 ^ i3 =" + (i1 ^ i3));
}
//结果:
i1 ^ i2 = 3
i1 ^ i3 = 2
5、"<<" 左移运算(右边补0,向左移动)
public static void example5() {
int i1 = 1; //0001
int i3 = 3; //0011
/** 二进制 十进制
* 0 ... 0001 1 0 ... 0011 3 0 ... 0011 3
* << << <<
* _____________________________________________________________________________________
* 0 ... 0010 2 0 ... 0110 6 0 ... 1100 12
**/
System.out.println("i1 << 1 = " + (i1 << 1));
System.out.println("i3 << 3 = " + (i3 << 1));
System.out.println("i3 << 3 = " + (i3 << 2));
}
//结果:
i1 << 1 = 2
i3 << 3 = 6
i3 << 3 = 12
6、">>" 右移运算(正数,左边补0,向右移动;负数,左边补1,向右移动)
public static void example8() {
int i1 = 1; //0001
int i2 =-1; //1... 0001
int i3 = 3; //0011
/** 二进制 十进制
* 0 ... 0001 1 1 ... 0001 -1 0 ... 0011 3
* >> >> >>
* _____________________________________________________________________________________
* 0 ... 0000 0 1 1... 0000 (反码) -1 0 ... 0000 0
**/
System.out.println("i1 >> 1 = " + (i1 >> 1));
System.out.println("i2 >> 1 = " + (i2 >> 1));
System.out.println("i3 >> 3 = " + (i3 >> 2));
}
//结果:
i1 >> 1 = 0
i2 >> 1 = -1
i3 >> 3 = 0
7、">>>"无符号右移(无视符号位,右移都补0)
public static void example6() {
int i1 = 1;
int i2 = -2;
/** 二进制 十进制
* 0 ... 0001 1 1 ... 0010 -2 1 ... 0010 -2
* >>> >>> >>>
* _____________________________________________________________________________________
* 0 ... 0000 0 0 1... 0000 0 11 ... 0000
**/
System.out.println("i1 >>> 1 =" + (i1 >>> 1));
System.out.println("i2 >>> 1 =" + (i2 >>> 1));
System.out.println("i2 >>> 2 =" + (i2 >>> 2));
}
//结果:
i1 >>> 1 =0
i2 >>> 1 =2147483647
i2 >>> 2 =1073741823
8、"~" 取反运算
public static void example4() {
int i1 = 1; //0001 1110 1...0001 + 0001 =0010 = -2
int i2 = 0; //0000 1111 1...0000 + 0001 =0001 = -1
/** 二进制 十进制
* 0 ... 0001 1 0 ... 0000 0
* ~ ~
* 1 ... 1110 1 ... 1111
* 1 ... 0001 1 ... 0000
* + +
* 0 ... 0001 0 ... 0001
* ___________________________________________________________
* 1 ... 0010 -2 1 ... 0001 -1
**/
System.out.println("~i1 = " + (~i1));
System.out.println("~i2 = " + (~i2));
}