You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

霍夫曼压缩中,将比特写入大端字节序的方式是否正确?

霍夫曼压缩大端字节序存储二进制编码的实现方案

嘿,我完全懂你在霍夫曼压缩里卡到的这个点——大端字节序下把零散的二进制编码塞进unsigned char里,说起来简单但实际操作总容易搞混比特位的位置,尤其是像1101这种非整字节的编码,查帖子找不到清晰答案确实闹心!我来给你一步步讲明白:

核心逻辑:大端字节序的比特填充规则

大端的核心是高位比特优先存储,也就是说我们要从unsigned char的最高位(第7位,二进制从左到右数第一个位置)开始,往最低位(第0位)依次填充霍夫曼编码。比如你要存1101这4位,最终的字节应该是11010000——前4位是你要存的编码,剩下的低位补0留着后续填充。

具体操作步骤(附代码示例)

假设我们从初始值为00000000的unsigned char开始:

1. 存入单段短编码(比如1101,4位)

首先把编码转换成十进制(1101对应十进制13),然后根据编码长度计算左移位数:左移位数 = 8 - 编码长度。因为要把编码放到字节的最高位区域,所以:

unsigned char byte = 0; // 初始00000000
// 1101对应十进制13,左移4位(8-4)放到高位
byte |= (13 << 4);
// 现在byte的值是0xD0,二进制为11010000

2. 继续填充后续编码(比如再存10,2位)

如果后续还有编码要存,需要先记录已经用掉的比特位数(这里已经用了4位),然后计算新编码的左移位数:左移位数 = 8 - 已用位数 - 新编码长度。把新编码左移后和当前字节做或操作,就能把编码填到下一段高位位置:

// 10对应十进制2,已用4位,新编码2位,左移位数=8-4-2=2
byte |= (2 << 2);
// 现在byte的值是0xD8,二进制为11011000

3. 处理跨字节的长编码

如果遇到剩余比特位不够存当前编码的情况(比如当前字节还剩3位,但要存5位的编码10110),拆分两步处理:

  • 先取编码的前3位101(十进制5),直接填充到当前字节的剩余位置:
// 当前byte已用5位,剩余3位
byte |= 5; // 5是101,直接填到剩余低位
// 现在byte是原已填充的5位 + 101
  • 剩下的2位10(十进制2),放到新的unsigned char里,左移6位(8-2)放到新字节的高位:
unsigned char new_byte = 0;
new_byte |= (2 << 6);
// new_byte的值是0x80,二进制为10000000

总结一下关键思路

每次填充编码时,都要先确定当前字节的剩余可用高位位置,把编码左移到对应位置后通过或操作合并到字节里——这样就能严格遵循大端字节序的存储规则,保证霍夫曼编码的正确存储和后续解码。

内容的提问来源于stack exchange,提问作者Ji Kang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:07:39