位元運算就是對二進位的 0 和 1 做一些處理,然後會有一些很神奇的性質和用途。
bool 只有 true 跟 false,然後可以對它們做一些運算:
| 符號 | C++ | |
|---|---|---|
| AND | a && b | 
|
| NOT | !a | 
|
| OR | a || b | 
|
| XOR | a != b | 
其中比較奇怪的東西是 xor 在兩個運算元中有恰一個是 true 時,結果是 true,反之就是 false。你可能會想蛤 != 不是不等於嗎,其實只有兩個運算元的 xor 就是不等於的意思。(有時候會遇到超過兩個東西一起 xor,這個時候 XOR 的定義是有奇數個是 true 時結果為 true。)
進入正題,除了 bool 可以做以上那些運算以外,int、long long 這樣的整數型態也可以做這些運算,做法就是每個位元分別做運算,例如:
| bit | 5 | 4 | 3 | 2 | 1 | 0 | 
|---|---|---|---|---|---|---|
| A | 1 | 0 | 0 | 1 | 1 | 0 | 
| B | 0 | 1 | 1 | 0 | 0 | 0 | 
| ANS | 1 | 1 | 1 | 1 | 1 | 0 | 
這叫做 bitwise operation。
以下是 C++ 的位元運算子列表:
| 運算子 | 說明 | |
|---|---|---|
| AND | A & B | 
bitwise and | 
| OR | A | B | 
bitwise or | 
| XOR | A ^ B | 
bitwise xor | 
| 左移 | A << n | 
將 A 的每個位元左移 0 | 
| 右移 | A >> n | 
將 A 的每個位元右移 0 或 1 依 A 本來的最高位決定 | 
| NOT | ~A | 
bitwise not,將 A 為 0 的位元換成 1,為 1 換成 0,也就是取補數 | 
一些範例:
0 還是 1: 1  | A & (1 << n) //>0 的話為 1,否則為 0  | 
1  | ~A+1  | 
1 以外的 1 都換成 0: 1  | A & -A  | 
1  | a <<= 1 // a *= 2  | 
因為 xor 太多常用性質,所以特別拿出來講。先來幾個基本原則:
這些只要稍微想一下就可以得出來了,如果覺得很難想,可以先用只有一個 bit 的狀況來想,反正每一個位元互不干擾。
舉例來說,把兩個變數 a、b 互換可以這樣做: 1
2
3a = a ^ b;
b = a ^ b;
a = a ^ b;
稍微解釋一下,若
a、b的原始值分別為、 ,新值為 、 ,那麼: 
設
可以發現到在做 xor 時,每個人都是自己的反元素,因為