位運算符是做用於整數的運算對象,把運算對象當作二進制的集合。測試
運算符 | 功能 | 用法 |
~ | 按位求反 | ~expr |
<< | 按位左移 | expr1 << expr2 |
>> | 按位右移 | expr1 >> expr2 |
& | 按位與 | expr1 & expr2 |
^ | 按位異或 | expr1 ^ expr2 |
| | 按位或 | expr1 | expr2 |
按位求反(~)
將運算對象的二進制逐位求反,將1置爲0,將0置爲1,後獲得一個新的值。ui
int j = 10; cout << (~j) << endl;//-11
按位左移(<<)
將運算對象的二進制位往左移動n位,右邊以數字0補充空出來的二進制位,後獲得一個新的值。一個數m往左移動n位後(移動的範圍在容器的範圍內),那麼新的值將會是m*2n。spa
int j = 10; cout << (j << 2) << endl;//40
按位右移(>>)
將運算對象的二進制位往右移動n位,左邊以0或1補充,具體的實現規則要根據具體的環境而定。一般狀況下,如果負數那麼左邊補充1,如果正數那麼左邊補充0。一個浮點數m往右移動n位後,那麼新的值將會是floor(m / 2n),其中floor(x)返回一個小於或等於浮點數x的最大的整數。code
int j = 10; cout << (j >> 2) << endl;//2 j = -10; cout << (j >> 2) << endl;//-3
按位與(&)
將兩個運算對象的二進制逐位執行與的邏輯操做,只有兩個相同位置都是1,結果纔是1;不然是0。對象
int j = 10; int i = 3; cout << (j & i) << endl; //2
按位或(|)
將兩個運算對象的二進制逐位執行或的邏輯操做,兩個相同位置只要有一個是1,結果就是1;不然爲0。blog
int j = 10; int i = 3; cout << (j | i) << endl; //11
按位異或(^)
將兩個運算對象的二進制逐位指向異或的邏輯操做,兩個位相同,結果爲0;不然爲1。table
int j = 10; int i = 3; cout << (j ^ i) << endl; //9
口訣:class
按位與(&),兩個都是1,纔是1。
按位或(|),只要有一個爲1,就是1。
按位異或(^),相同的爲0,不一樣的爲1。
位運算符的使用案例
假設班級中有30個學生,老師每週都會對學生進行一次小測試,測試結果只有經過和不經過兩種。咱們用二進制位表明某個學生在一次測試中是否經過,顯然全班學生能夠用一個無符號整數來表示:容器
unsigned long quiz1 = 0;
這裏之因此使用long而不是用int,是由於long在每臺機器上至少都有32位(有30個學生,能夠知足要求),而int不能保證在每臺機器上都有32位(int的最小大小是16位)。
教師必須有權檢查每個二進制位。例如:咱們須要對序號爲27的學生進行對應的位設置,以表示它經過測驗。爲了達到這一目的,首先建立一個值,該值只有第27位是1,其它位是0,而後再將這個值與quiz1進行或運算,這樣就能將quiz1的第27位設置爲1,其它位不變。
爲了實現這個目的,須要使用左移運算符和一個unsigned long類型的整數字面值1就能獲得學生第27號學生經過檢測的數值:二進制
1UL << 27;//UL 是unsigned long類型
接下來與quiz1進行或運算:
quiz1 |= 1UL << 27;//將第27位改成1(經過測試)
假設在從新覈對測試結果後發現第27號學生並無經過測試,他必須將第27位置爲0。此時須要一個特殊的整數,它的第27位是0,其它位是1,而後將這個值與quiz1進行安位與運算,所得結果除了第27位變成0,其它位都沒變。
quiz1 &= ^(1UL << 27);//將第27位改成0(未經過測試)
最後,咱們試圖檢測第27位學生的測試狀況到底怎麼樣:
bool status = quiz1 & (1UL << 27);
若是quiz1的第27位是1,那麼計算結果就是非0(真),不然結果是0。