基礎算術替換(2 的冪次場景)
| 操作 | 位運算 | 等價算術 | 適用條件 |
| 除法取商 | a >> n | a / 2^n | 正數、2 的冪次除數 |
| 乘法 | a << n | a * 2^n | 無溢出風險 |
| 取模 | a & ((1 << n) - 1) | a % 2^n | 正數、2 的冪次模數 |
| 奇偶判斷 | (a & 1) == 1 | a % 2 == 1 | 整數 |
標誌位操作模式(1=開啟/選中,0=關閉/未選)
| 需求 | 位運算表達式 | 口訣 |
| 全選掩碼 | (1 << n) - 1 | n 位全 1 |
| 單個位掩碼 | 1 << idx | 第 idx 位為 1 |
| 反選 | ~a | 按位取反 |
| 開啟指定位 | a |= b | 或賦值 |
| 合併兩組選項 | a | b | 按位或 |
| 關閉指定位 | a &= ~b | 與非賦值:遇 1 變 0 |
| 查看公共項 | a & b | 按位與 |
| 保留指定位 | a &= b | 與賦值:遇 0 變 0 |
| 切換指定位 | a ^= b | 異或賦值:遇 1 翻轉 |
| 查看變化位 | a1 ^ a2 | 前後異或 |
| 查看不變位 | ~(a1 ^ a2) | 變化位取反 |
組合輸出實戰:生成 "abcd" 所有非空子集
public static void main(String[] args) {
char[] chars = "abcd".toCharArray();
int len = chars.length;
int all = (1 << len) - 1; // 1111
for (int i = all; i > 0; i = (i - 1) & all) { // 灰碼遍歷所有子集
System.out.printf("%" + len + "s:", Integer.toBinaryString(i));
for (int j = 0; j < len; j++) {
if (((i >> j) & 1) == 1) System.out.print(chars[j]);
}
System.out.println();
}
}
輸出:從 abcd 遞減至 a,共 15 種組合。
移位陷阱與工具類
- 符號右移
>>:正數補 0,負數補 1(保持符號)。
- 無符號右移
>>>:始終補 0。
JDK 內置工具:
Integer.bitCount(int) / Long.bitCount(long) — 統計 1 的個數(人口計數)。
java.util.BitSet — 突破 64 位限制的動態位向量,核心方法:
| 方法 | 對應位運算 | 說明 |
cardinality() | bitCount | 1 的個數 |
and(bs) | &= | 保留公共位 |
or(bs) | |= | 合併開啟位 |
xor(bs) / flip() | ^= | 翻轉指定位 |
andNot(bs) | &= ~ | 關閉目標位 |
get/set/clear(index) | 單位操作 | 讀/寫/清除指定位 |
previous/nextSetBit() | — | 查找前/後一個 1 的索引 |
toLongArray()/toByteArray() | — | 序列化輸出 |