位運(yùn)算不管是在Java語言,還是在C語言中,或者其他語言,都會(huì)經(jīng)常用到。位運(yùn)算主要包括按位與(&)、按位或(|)、按位異或(^)、取反(~)、左移(<<)、右移(>>)這幾種,其中除了取反(~)以外,其他的都是二目運(yùn)算符,即要求運(yùn)算符左右兩側(cè)均有一個(gè)運(yùn)算量。
1、補(bǔ)碼
在總結(jié)按位運(yùn)算前,有必要先介紹下補(bǔ)碼的知識(shí),我們知道當(dāng)將一個(gè)十進(jìn)制正整數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的時(shí)候,只需要通過除2取余的方法即可,但是怎么將一個(gè)十進(jìn)制的負(fù)整數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)呢?其實(shí),負(fù)數(shù)是以補(bǔ)碼的形式表示。其轉(zhuǎn)換方式,簡單的一句話就是:先按正數(shù)轉(zhuǎn)換,然后取反加1。
2、按位與(&)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行與運(yùn)算。只有當(dāng)相應(yīng)位上的數(shù)都是1時(shí),該位才取1,否則該位為0。
3、按位或(|)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行或運(yùn)算。只要相應(yīng)位上存在1,那么該位就取1;如果均不為1,即為0。
4、按位異或(^)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行異或運(yùn)算。只有當(dāng)相應(yīng)位上的數(shù)字不相同時(shí),該位才取1;若相同,即為0。
可以看出,任何數(shù)與0異或,結(jié)果都是其本身。利用異或還可以實(shí)現(xiàn)一個(gè)很好的交換算法,用于交換兩個(gè)數(shù),算法如下:
5、取反(~)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行取反運(yùn)算。每個(gè)位上都取相反值,1變成0,0變成1。
6、左移(<<)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行左移運(yùn)算,用來將一個(gè)數(shù)各二進(jìn)制位全部向左移動(dòng)若干位。
注意,觀察可以發(fā)現(xiàn),左移一位的結(jié)果就是原值乘2,左移兩位的結(jié)果就是原值乘4。
7、右移(>>)
參加運(yùn)算的兩個(gè)數(shù),換算為二進(jìn)制(0、1)后,進(jìn)行右移運(yùn)算,用來將一個(gè)數(shù)各二進(jìn)制位全部向右移動(dòng)若干位。
注意,觀察可以發(fā)現(xiàn),右移一位的結(jié)果就是原值除以2,右移兩位的結(jié)果就是原值除以4,注意,除了以后結(jié)果沒有小數(shù)位,都是取整。
Java中>>和>>>的區(qū)別:
- 對于正數(shù)而言,>>和>>>沒區(qū)別。
- 對于負(fù)數(shù)而言,-2 >>> 1,結(jié)果是2147483647(Integer.MAX_VALUE);-1 >>>1,結(jié)果是2147483647(Integer.MAX_VALUE)。
所以,要判斷兩個(gè)數(shù)符號是否相同時(shí),可以這么干:
return ((a >> 31) ^ (b >> 31)) == 0;