什麼是位元位移?
位元位移(bit shift)就是把一個整數的二進位數字,往左或往右移動指定的位數。位移是程式設計中最基礎的運算之一,廣泛應用於底層效能最佳化、圖形處理、雜湊運算與嵌入式系統。左移(n << k)會把位元往最高位(MSB)方向推,右側空出的位置補 0;右移(n >> k)則把位元往最低位(LSB)方向推。
如何使用這個計算機
輸入整數 n、位移量 k(以位元為單位),再選擇位移方向,計算機就會回傳運算後的十進位數值。本工具採用 64 位元有號整數運算,與多數程式語言的行為一致。
公式解析
每往左移一位,數值就會乘以 2,因此往左移 k 位等同於乘上 \(2^{k}\):
$$\text{Result} = \text{Number (n)} \ll \text{Shift (k)} = n \times 2^{k}$$每往右移一位,數值則會除以 2 並向下取整,所以往右移 k 位相當於做以 \(2^{k}\) 為除數的整數除法:
$$\text{Result} = \text{Number (n)} \gg \text{Shift (k)} = \left\lfloor \frac{n}{2^{k}} \right\rfloor$$這也正是為什麼在硬體上,位移運算的成本遠低於乘法或除法。
實際範例
假設 \(n = 16\),往左移 \(k = 2\) 位。16 的二進位是 10000,往左移兩位等於在右側補上兩個 0:1000000,也就是 64。用數學來算就是 \(16 \times 2^{2} = 16 \times 4 = 64\)。反過來看,\(64 \gg 2 = \left\lfloor 64 / 4 \right\rfloor = 16\),剛好回到原本的數值。
二的冪次參考表
左移 \(k\) 位將數字乘以 \(2^k\);右移 \(k\) 位除以 \(2^k\)(整數情況下捨棄餘數)。使用此表可以立即讀出給定移位量的乘數或除數。
| 移位 \(k\) | \(2^k\)(十進制) | \(\ll k\) / \(\gg k\) 的含義 |
|---|---|---|
| 0 | 1 | 無變化 |
| 1 | 2 | \(\times 2\) / \(\div 2\) |
| 2 | 4 | \(\times 4\) / \(\div 4\) |
| 3 | 8 | \(\times 8\) / \(\div 8\) |
| 4 | 16 | \(\times 16\) |
| 5 | 32 | \(\times 32\) |
| 6 | 64 | \(\times 64\) |
| 7 | 128 | \(\times 128\) |
| 8 | 256 | \(\times 256\)(1 位元組) |
| 9 | 512 | \(\times 512\) |
| 10 | 1,024 | \(\times 1024\)(1 KiB) |
| 11 | 2,048 | \(\times 2048\) |
| 12 | 4,096 | \(\times 4096\) |
| 13 | 8,192 | \(\times 8192\) |
| 14 | 16,384 | \(\times 16384\) |
| 15 | 32,768 | \(\times 32768\) |
| 16 | 65,536 | \(\times 65536\)(2 位元組) |
| 17 | 131,072 | |
| 18 | 262,144 | |
| 19 | 524,288 | |
| 20 | 1,048,576 | \(\times\) 1 MiB |
| 32 | 4,294,967,296 | 32 位元邊界 |
| 63 | 9,223,372,036,854,775,808 | 64 位元帶符號整數的最高位 |
常見問題
左移會不會遺失資料?會。超出整數位寬的位元會被捨棄(也就是溢位)。不過在 64 位元範圍內,本計算機都能完整保留數值。
負數做右移時會怎麼樣?本計算機採用算術(有號)右移,會保留符號位元,因此負數位移後仍維持負值。
為什麼要用位移取代乘法或除法?在多數 CPU 上,位元位移只需一個時脈週期就能完成,因此用來做 2 的次方乘除運算特別快速。