現代電腦通用二補數表示有號整數,最高位為符號位。
十進位負數 → 二進位:加 1 → 取絕對值 → 轉二進位 → 求補。
二進位負數 → 十進位:求補 → 轉十進位 → 變號 → 減 1。
範例 -5 (8-bit):-5 → -4 → 4 → 00000100 → 11111011。
32 位 int 範圍:-2^31 ~ 2^31-1;unsigned int:0 ~ 2^32-1。
x & 0xF 保留低 4 位。x | 0xF 置低 4 位為 1。void swap(int *a, int *b) {
*a ^= *b; *b ^= *a; *a ^= *b;
}
0 ^ 0x7FFFFFFF 得最大正整數。假設 unsigned int 為 32 位,提供通用工具函數:
int int_size() {
unsigned int bits = ~0;
int size = 0;
while (bits) { ++size; bits >>= 1; }
return size;
}
unsigned int bit_shift(unsigned int value, int n) {
int sz = int_size();
if (n > 0 && n < sz) value <<= n;
else if (n < 0 && n > -sz) value >>= -n;
else value = 0;
return value;
}
unsigned int bit_rotate(unsigned int value, int n) {
int sz = int_size();
if (n > 0) n %= sz; else n = -(-n % sz);
if (n == 0) return value;
if (n > 0) { // 左旋
unsigned int bits = value >> (sz - n);
return (value << n) | bits;
} else { // 右旋
n = -n;
unsigned int bits = value << (sz - n);
return (value >> n) | bits;
}
}
int bit_get(unsigned int value, int p) {
int sz = int_size();
if (p < 0 || p >= sz) return 0;
return (value >> p) & 1;
}
unsigned int bit_set(unsigned int value, int p) {
int sz = int_size();
if (p < 0 || p >= sz) return 0;
return value | (1u << p);
}
unsigned int bits_get(unsigned int value, int p, int n) {
int sz = int_size();
if (n < 0 || p < 0 || p + n > sz) return 0;
return (value >> (p + 1 - n)) & ~(~0u << n);
}
關鍵:~(~0u << n) 產生低 n 位全 1 遮罩。
unsigned int bits_set(unsigned int value, int p, int n, unsigned int y) {
int sz = int_size();
if (n < 0 || p < 0 || p + n > sz) return 0;
unsigned int mask = ~(~(~0u << n) << (p + 1 - n)); // 目標位清 0,其餘 1
unsigned int src = bits_get(y, n-1, n); // 取 y 低 n 位
return (value & mask) | src;
}
1u, ~0u 明確無號常數。0xFF)或巨集(BIT(n))提升可讀性。READ_REG/WRITE_REG 宏封裝 volatile 存取。__builtin_popcount (GCC/Clang) 等內建函數加速位計數。位元運算是系統程式、嵌入式、演算法優化的基石,熟練掌握上述模式能寫出高效、精簡的底層代碼。