真者,精诚之至也,不精不诚,不能动人。——《庄子·渔夫》
一、二进制位运算(运行速度相当快)
(1)、按位与 &
对应两位全为1,结果才为1。譬如:0&0=0;0&1=0;1&0=0;1&1=1;
51&5=1
51=0011 0011
5 =0000 0101
& =0000 0001=1
按位与 &位运算的特殊用法:
1、清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
2、取一个数中指定位
例:设X=10101110,取X的低4位,用X & 0000 1111=0000 1110 即可得到
方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。
(2)、按位或 |
只要有一个为1,结果就为1。譬如:0|0=0;0|1=1;1|0=1;1|1=1;
51&5=55
51=0011 0011
5 =0000 0101
& =0011 0111=1
按位或|位运算的特殊用法:
常用来对一个数据的某些位设置为1
譬如:将X=1010 0000低4位设置为1,用X|0000 1111=1010 1111即可得到
方法:找到一个数,对应X要设置为1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位设置为1
(3)、异或运算 ^
两个相应位为“异”(值不同),则该位结果为1,否则为0 譬如:0&0=0;0&1=1;1&0=1;1&1=0;
51&5=54
51=0011 0011
5 =0000 0101
& =0011 0100=54
异或^位运算的特殊用法:
1、使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。
例:X=10101110,使X低4位翻转,用X^0000 1111=1010 0001即可得到。
2、与0相异或,保留原值
例:X^0000 0000=1010 1110
3、两个变量交换值的方法
1、C=A;A=B;B=C;借助第三个变量来实现
2、A=A+B;B=A-B;A=A-B;利用加减法实现两个变量的交换
3、利用位异或运算来实现,也是效率最高的。原理:利用一个数异或本身等于0和异或运算符合交换率
如:A=A^B;B=A^B;A=A^B;
(4)、取反运算~:对数据的每个二进制位取反,即把1变为0,把0变为1
(5)、算术左移<<:高位溢出,符号位不变,低位补0。若左移舍弃的高位不包括1,每左移一位相当于乘2,而且比乘法运算速度要快
11(1011)<<2=44 (11是整数,4个节字32bit所以前面我们省略了24个0,左移二位相当于去掉2个0)
-14<<2=-56 负数是以其正值的补码形式表示的,其实正数也是以补码形式运算的,因为正数的原码、反码、补码都一样。补码=它的反码+1
14=00000000 00000000 00000000 00001110
~=11111111 11111111 11111111 11110001
补=11111111 11111111 11111111 11110010
<<2=11111111 11111111 11111111 11001000
只需要该补码的原码对应的正值,然后取相反数
1、补码-1得到反码(11000111)
2、反码取反得到原码(即该负数的正值)(00111000)
3、计算正值为56
(6)、算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位。右移一位相当于除2取商
4>>2=1
(7)、逻辑右移>>>: 低位溢出,高位补0
二、数据类型转化字节
譬如:int 转化字节
8143(00000000 00000000 00011111 1100111)
->byte[]b=[-49,31,0,0]
使用了按位与运算取一个数中指定位.0xff是16进制,转换为10进制即:=15*15=255,转换为2进制即:11111111即0xff=11111111
第一个(低端)字节:8143>>0*8 & 0xff=(11001111)=207(或有符号-49)
第二个(低端)字节:8143>>1*8 & 0xff=(11001111)=31
第三个(低端)字节:8143>>2*8 & 0xff=(11001111)=0
第四个(低端)字节:8143>>3*8 & 0xff=(11001111)=0
示例一:
public class Convert {
/**
* int转化为byte[]字节
*/
public static byte[] int2Bytes(int id){
byte[] arr=new byte[4];
// arr[0]=(byte) ((id>>0*8) & 0xff);
// arr[1]=(byte) ((id>>1*8) & 0xff);
// arr[2]=(byte) ((id>>2*8) & 0xff);
// arr[3]=(byte) ((id>>3*8) & 0xff);
for(int i=0;i<arr.length;i++){
arr[i]=(byte) ((id>>i*8) & 0xff);
}
return arr;
}
/**
* byte[]转为int
* @param args
*/
public static int bytes2Int(byte[] arr){
int result=0;
for(int i=0;i<arr.length;i++){
result+=(int)((arr[i] & 0xff)<<i*8);
}
return result;
}
/**
* long转化为byte[]字节
*/
public static byte[] long2Bytes(long id){
byte[] arr=new byte[8];
for(int i=0;i<arr.length;i++){
arr[i]=(byte) ((id>>i*8) & 0xff);
}
return arr;
}
/**
* byte[]转为long
* @param args
*/
public static int bytes2Long(byte[] arr){
int result=0;
for(int i=0;i<arr.length;i++){
result+=(long)((arr[i] & 0xff)<<i*8);
}
return result;
}
public static void main(String[] args) {
byte[] arr=Convert.int2Bytes(8143);
System.out.println(Arrays.toString(arr));
System.out.println(Convert.bytes2Int(arr));
byte[] arr1=Convert.long2Bytes(1245625);
System.out.println(Arrays.toString(arr1));
System.out.println(Convert.bytes2Long(arr1));
//字符串与字节数组
String str="你好ABC";
byte[] b=str.getBytes();//把字符串转换成一个字节数组
System.out.println(Arrays.toString(b));
//字节数组转换成字符串
String str2=new String(b);
System.out.println(str2);
}
}
示例二:进制转换
public class Test {
public static void main(String[] args) {
//十进制转为其它进制
System.out.println("20十进制转为二进制 "+Integer.toBinaryString(20));
System.out.println("20十进制转为八进制 "+Integer.toOctalString(20));
System.out.println("20十进制转为十六进制 "+Integer.toHexString(20));
//其它进制转为十进制
System.out.println("101二进制转为十进制 "+Integer.parseInt("101",2));
System.out.println("101八进制 转为十进制 "+Integer.parseInt("101",8));
System.out.println("101十六进制 转为十进制 "+Integer.parseInt("101",16));
}
}
结果:
20十进制转为二进制 10100
20十进制转为八进制 24
20十进制转为十六进制 14
101二进制转为十进制 5
101八进制 转为十进制 65
101十六进制 转为十进制 257