位平移压缩是通过左移、右移和掩码将多个小整数打包进大整数,实现极致紧凑存储;适用于嵌入式、协议封装等场景,核心公式为(packed>>k)&mask。

位平移压缩本质是利用左移()和右移(>>)把多个小范围整数“打包”进一个更大的整数中,再通过掩码提取还原。它不依赖额外结构体或数组,空间极致紧凑,适合嵌入式、协议字段封装、状态缓存等场景。
明确压缩目标与位宽分配
先确定你要压缩的变量个数和各自取值范围。例如:用一个 32 位 int 存储 4 个温度值,每个温度在 0–15(即 4 位可表示)。那么总需 4 × 4 = 16 位,远低于 32 位上限,留有余量。
分配方式示例(从低位开始):
- temp0 占第 0–3 位(bit 0 ~ 3)
- temp1 占第 4–7 位(bit 4 ~ 7)
- temp2 占第 8–11 位(bit 8 ~ 11)
- temp3 占第 12–15 位(bit 12 ~ 15)
打包:用左移 + 按位或组合数值
将每个值左移到对应位置,再用 | 合并:
int pack(int t0, int t1, int t2, int t3) {
return (t0 & 0xF) // 保证只取低4位
| ((t1 & 0xF) << 4)
| ((t2 & 0xF) << 8)
| ((t3 & 0xF) << 12);
}
注意:& 0xF 是关键防护——防止输入越界导致高位污染;左移前做掩码比移后掩码更安全。
解包:用右移 + 按位与提取数值
把对应段右移到最低位,再用掩码截取低 4 位:
int get_t0(int packed) { return packed & 0xF; }
int get_t1(int packed) { return (packed >> 4) & 0xF; }
int get_t2(int packed) { return (packed >> 8) & 0xF; }
int get_t3(int packed) { return (packed >> 12) & 0xF; }
核心公式统一为:(packed >> k) & mask,其中 k 是起始位偏移,mask 是该字段位宽对应的全 1 掩码(如 4 位 → 0xF,5 位 → 0x1F)。
扩展技巧:支持动态位宽与溢出检查
若字段位宽不固定(如有的 3 位、有的 5 位),可预定义偏移数组和掩码数组:
const int OFFSET[] = {0, 3, 8, 13}; // 各字段起始位
const int MASK[] = {0x7, 0x1F, 0xF, 0x3}; // 对应位宽掩码(3/5/4/2位)
// 打包第 i 个值:(val & MASK[i]) << OFFSET[i]
上线前建议加断言:assert((val & ~MASK[i]) == 0),确保输入未超限,避免静默错误。

















