运算符优先记忆方法:
单目乘除为关系,逻辑三目后赋值
-
单目运算符(单目):一次作用一个变量的运算符,又叫一元运算符
+、/(正负)、++、–、!(逻辑非)、~(按位取反) -
算数运算符(乘除):*、/、%、+、-,(+、-的优先级肯定小于前三个)
-
位运算符(为):~(按位取反)、<<(左移)、>>(右移)、^(异或)
-
关系运算符(关系):>、<、>=、<=、==、!=
-
逻辑运算符(逻辑):&&、||、&、|(与的优先级>或的优先级)
-
条件运算符(三目):true ? 1:2
-
后是无意义的
-
赋值运算符:=、+=、-=、*=、/=、%=、|=、&=、^=
**注意:**前优先级大于后优先级,比如‘~’运算符,即是位运算符,也是单目运算符,单目运算符大于位运算符,所以是单目级别的。
二进制的简单计算
首先我们需要先了解一下二进制的简单计算,比如原码、反码、补码的运算。
原码:最高位为符号位 0正 1负 ,其余为表示数值大小。
反码:正数反码和原码相同,负数的反码是其原码逐位取反 (符号位除外)。
补码:正数补码和原码相同,负数的补码是在其反码末+1.
原码 | 反码 | 补码 | |
---|---|---|---|
7 | 00000000 00000000 00000000 00000111 | 00000000 00000000 00000000 00000111 | 00000000 00000000 00000000 00000111 |
-7 | 10000000 00000000 00000000 00000111 | 11111111 11111111 11111111 11111000 | 11111111 11111111 11111111 11111001 |
由上图我们可以计算出7和-7的补码,
在计算机系统中,数值一律用补码来表示(存储)。
主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
%(模):-10%3=-1 取余结果的正负号跟被除数的正负号相同。
/(除):若两个数相除则结果取整。(不纠结怎么取整,只取整数部位)
位运算过程图,纯属个人理解:
位运算符的解析:
按位与 | & | 有0则0,其他为1 |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
5 | 00000000 00000000 00000000 00000101 | |
-7&5 | 00000000 00000000 00000000 00000001 | 1 |
正数的原码、反码、补码都一样不需要再计算(补码变反码-1)。
按位或 | | | 有1则1,其他为0 |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
5 | 00000000 00000000 00000000 00000101 | |
-7|5 计算完的补码 | 11111111 11111111 11111111 11111101 | |
-7|5 计算完的反码 | 11111111 11111111 11111111 11111100 | |
-7|5 的原码 | 10000000 00000000 00000000 00000011 | -3 |
按位异或 | ^ | 相同为0,不同为1 |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
5 | 00000000 00000000 00000000 00000101 | |
-7^5 计算完的补码 | 11111111 11111111 11111111 11111100 | |
-7^5 计算完的反码 | 11111111 11111111 11111111 11111011 | |
-7^5 的原码 | 10000000 00000000 00000000 00000100 | -4 |
注意:一个数异或两次,值不变。
题:实现两个数变量的交换,只采用两个变量。
按位取反 | ~ | 翻转每一位(包括符号位) |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
~ -7 的补码 | 00000000 00000000 00000000 00000110 | 6 |
5 | 00000000 00000000 00000000 00000101 | |
~5 的补码 | 11111111 11111111 11111111 11111010 | |
~5 的反码 | 11111111 11111111 11111111 11111001 | |
~5 的原码 | 10000000 00000000 00000000 00000100 | -6 |
可以看出来(~5)=-6,(-6)=5,(~6)=-7 ,(~7)=-8 |
短路与 | && | 如果前面是false,则后面不执行 |
---|
&&和 & 的区别:&会全部执行完,而&&如果前面是false,则后面不执行。 (但执行结果是一样的)
短路或 | || | 如果前面是true,则后面不执行 |
---|
||和|的区别:|会执行完,|| 如果前面是true,则后面不执行。(但执行结果是一样的)
按位左移 | << | 右补,最高位不变,低位补0。 |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
-7<<2的补码 | 11111111 11111111 11111111 11100100 | |
-7<<2的反码 | 11111111 11111111 11111111 11100011 | |
-7<<2的原码 | 10000000 00000000 00000000 00011100 | -28 |
简便算法(-7<<2)=-(7*2*2)= -28 (16<<2)=(16*2*2)=64
按位右移 | >> | 左补,最高位不变,低位溢出,符号位不变,用当前的符号位补,负数用1补,正数用0补。 |
---|---|---|
计算 | 补码 | 结果 |
-7 | 11111111 11111111 11111111 11111001 | |
-7>>2的补码 | 11111111 11111111 11111111 11111110 | |
-7>>2的反码 | 11111111 11111111 11111111 11111101 | |
-7>>2的原码 | 10000000 00000000 00000000 00000010 | -2 |
简便算法(-7>>2)=-(7*1/2*1/2)= -2 (向下取整) (16>>2)=(16*1/2*1/2)=4
无符号右移 | >>> | 没有无符号左移,都是正数时用法跟>>一样,当除数为负数时为0。 |
---|
题:计算2*8的最有效的运算。