写一些不常用的运算符,关系运算符和操作运算符不写,直接看逻辑运算符和位运算符,以位运算符为主。
逻辑运算符包括&& & || | ^ !,&&逻辑与 与&相比有短路现象就是当能确定结果后就不再继续判断,||逻辑或 与|相比同样是锻炼路现象。! 逻辑非就是变成两外一个真值,^ 逻辑异或 当两边同时为true 或者false时 逻辑或取false ,其它的取true。
重点写的是位关系,位关系虽然平时编程不常用但是在涉及到一些优化和面试题时有用,它操作对象是二进制,主要包括 &、|、!,>>,<<。首先应该明确几个计算机概念,原码,补码,反码,这个主要是涉及到负数如-15在计算机中表示,应该知道15在计算机中的表示(这里指的是int 型的)0(符号位)00……(25个0)……001111,那么它的原码、反码、补码都是这个这个不用考虑最高位的0表示符号(0表示正数,1表示负数),那么-15的表示很容易理解成1(符号位)00……(25个0)……001111其实不是这样的,负数的表示是通过补码,那么负数的补码怎么求?首页通过-15中的15求得-15的原码1(符号位)00……(25个0)……001111,然后再求反码(每个除符号位的其它位取反0取1,1取0)所以反码是1(符号位)11……(25个1)……110000,最后再加1就是补码1(符号位)11……(25个1)……110001,接下来上运行代码:
// 正数的原码 反码 补码都是一个
// 负数的原码是将最高位设为1其余的同正数原码 负数的反码是将除了表示符号的最高位外的其余位取反 负数的补码是再反码的基础上加1
int A=15;
int B=-15;
System.out.println(Integer.toBinaryString(A));
System.out.println(Integer.toBinaryString(B));
11111111111111111111111111110001
正数:
int b=4; //
int c=a&b;//
System.out.println(c);
运行结果:15
结果分析:15二进制是0(符号位)0……(25个0)……001111,4二进制是0(符号位)0……(25个0)……000100 所以结果是0……(25个0)……001111十进制15.
负数:
int b=-4; //
int c=a&b;//
System.out.println(c);
运行结果:12
结果分析:15二进制是0(符号位)0……(25个0)……001111,-4二进制原码是1(符号位)0……(25个0)……000100,由于计算机中存储的是它的补码所以求补码,先求反码:1(符号位)1……(25个1)……111011,补码:1(符号位)1……(25个1)……111100,所以结果是0(符号位)0……(25个0)……001100,结果为正就是原码十进制12.
位或,位非道理相同,只是位非患有一个直接求法位非-(x+1)。
下面看右位移(注意是正数补0负数补1与左位移不同):
int b3=-15;//
int c3=a3>>2; //
System.out.println(c3);
c3=b3>>2; //
System.out.println(c3);
运行结果:
-4
结果分析:15二进制是0(符号位)0……(25个0)……001111,右移两位左边进0,右边溢出的移出0(符号位)0……(25个0)……000011,十进制3.
-15二进制原码是1(符号位)0……(25个0)……001111,同样强调是计算机是对补码的操作,所以求反码1(符号位)1……(25个1)……110000,补码:1(符号位)1……(25个1)……110001,右移两位注意此时左边补得是1而不是0,右移后1(符号位)1……(25个1)……111100,此时是负数(最高位是1)求原码,先是反码1(符号位)1……(25个1)……111011,原码:1(符号位)0……(25个0)……000100,十进制-4.
左位移(不管正数还是负数都补0):
int b4=-10;//
int c4=a4<<2; //
System.out.println(c4);
c4=b4<<2; //
System.out.println(c4);
60
-40
结果分析:15二进制是0(符号位)0……(25个0)……001111,左移两位右边进0,左边溢出的移出0(符号位)0……(25个0)……111100,十进制2^6-1-1-2=60.
-10二进制是1(符号位)0……(25个0)……001010,负数同样计算机对其补码操作求补码,先是反码:1(符号位)1……(25个1)……110101,补码:1(符号位)1……(25个1)……110110,左移两位,右边不足的补0,左边移出溢出,1(符号位)1……(25个1)……011000,负值求原码,先是反码:1(符号位)1……(25个1)……010111,原码:1(符号位)0……(25个0)……101000 2^5+2^3=40, 结果是-40.
左移可以看作是乘以2的幂次方,右移当操作数是2的幂次方时可以看作是除以2的幂次方。