1.6 位运算
位运算是指对二进制数的运算,位运算虽然在工作中很少用到,但是其作用很大,如果经常看源码的道友一定经常看到位运算,如果不懂二进制位运算也就云里雾里了,在此笔者总结了下四个基本位运算的使用。
1.6.1 &运算
与运算是指两个二进制数相同位同时为1则结果为1。
System.out.println(Integer.toBinaryString(7)+"&"+Integer.toBinaryString(8));
System.out.println(7&8);
结果:
7:0111
8:1000
做与运算只需要看数字比较小的数的位数即可,如7的二进制是111,一个int用32位来存储,那么111前边全部是0做与运算永远为0,所以两个数做与运算只需要从数字比较小的那个数的最高位开始即可。
再来看下负数:
System.out.println(Integer.toBinaryString(-7)+"&"+Integer.toBinaryString(-8));
System.out.println(-7&-8);
-7的二进制为11111111111111111111111111111001
-8的二进制为11111111111111111111111111111000
首先需要明白计算机怎么表示负数的,负数的表示方式使用的补码,补码是指的取反加1。如上述的正数7的二进制是111,取反变成000,再加1则是001。
补充一句正数7的二进制111,int型用32位存,111前边全部是0,取反之后111变成了001,001前边也自然也是取反变成了1。
1.6.2 |运算
或运算则表示两个二进制数相同位有一个为1则为1。
System.err.println(Integer.toBinaryString(12)+"|"+Integer.toBinaryString(9));
System.err.println(12|9);
1100|1001等于1101,转换成10进制就是13。
再看下负数:
System.err.println(Integer.toBinaryString(-12)+"|"+Integer.toBinaryString(9));
System.err.println(-12|9);
注意或运算中由于负数的高位一定是1,所以两个数做或运算,只要有一个负数,则结果为负。 0的二进制表示为111…,所以0与任何数做或运算都为0。
1.6.3 ~运算
关于~运算即取反操作,或者说就是按位取反,1变成0,0变成1。
关于~操作的讲述网上很多都说的不太明白,这儿要明白二进制和十进制都是表示数的方式,表示的值并没有区别。比如1的二进制1,取反后变成0,高位从0变成1,所以计算机会以负数的方式读111…1110,就是-2。
System.err.println("~1="+(~1)+"="+Integer.toBinaryString(~1));
1.6.4 ^运算
^异或运算表示两个二进制数相同位值不同则为1,负责为0,只有当相同位组合为1与0时为1。
System.err.println("7^5="+
Integer.toBinaryString(7)+"^" +Integer.toBinaryString(5)+"=二进制"+
Integer.toBinaryString(7^5)+"=十进制"+(7^5));
1.6.5 小结
位运算还有很多神奇的操作,还有各种性质没有提到,比如在java.util集合框架源码里很多关于二进制的操作,其他java源码中也有很多二进制的运算,因为二进制运算效率更高,在越底层的代码里使用的也越多。笔者在此只是抛砖引玉待诸君深入,欢迎与笔者讨论。