如何将不同长度比特序列转换为字节数组(STM32F405+C环境)
解决方案
核心实现思路
用两个状态变量跟踪拼接过程,适配字节为最小操作单位的限制:
current_byte:正在填充的未完成字节(uint8_t类型)bit_count:当前字节已填充的比特数(范围0~7)
逐个处理每个Elias Gamma编码符号时,按以下逻辑操作:
- 把编码符号的比特位(按高位在前的顺序)填充到
current_byte的剩余空间 - 若填充后
bit_count达到8,将current_byte写入输出数组,重置状态变量 - 若编码符号还有剩余比特未填充,重复上述步骤直到整个符号处理完毕
- 所有符号处理完成后,若仍有不足8位的剩余比特,补零后写入输出数组
代码实现
先定义与查找表匹配的编码项结构体:
#include <stdint.h> #include <string.h> // 对应你的Elias Gamma编码查找表结构 typedef struct { uint32_t code; // 存储编码比特序列(高位在前) uint8_t length; // 编码的有效比特长度 } EliasGammaCode;
实现核心拼接函数:
/** * @brief 将多个Elias Gamma编码拼接成可传输的字节数组 * @param codes 编码数组指针 * @param code_num 待拼接的编码数量 * @param output 输出字节数组(需提前分配足够空间,最大长度为 (总比特数+7)/8) * @return 输出字节数组的实际长度 */ uint32_t elias_gamma_concat(const EliasGammaCode* codes, uint32_t code_num, uint8_t* output) { uint8_t current_byte = 0; uint8_t bit_count = 0; uint32_t output_idx = 0; for (uint32_t i = 0; i < code_num; i++) { uint32_t code = codes[i].code; uint8_t remaining_bits = codes[i].length; const uint8_t total_code_bits = codes[i].length; while (remaining_bits > 0) { // 计算当前字节剩余可填充的比特数 uint8_t available_bits = 8 - bit_count; uint8_t copy_bits = (remaining_bits < available_bits) ? remaining_bits : available_bits; // 提取编码中待填充的高位比特段 uint32_t shift_offset = total_code_bits - remaining_bits; uint8_t bits_segment = (code >> (32 - total_code_bits + shift_offset)) >> (8 - copy_bits); // 将比特段填充到当前字节的对应位置 current_byte |= bits_segment << (8 - bit_count - copy_bits); bit_count += copy_bits; remaining_bits -= copy_bits; // 当前字节填满,写入输出数组 if (bit_count == 8) { output[output_idx++] = current_byte; current_byte = 0; bit_count = 0; } } } // 处理最后剩余的不足8位的比特 if (bit_count > 0) { output[output_idx++] = current_byte; } return output_idx; }
测试示例
用你给出的三个编码验证功能:
int main(void) { EliasGammaCode test_codes[] = { {0b0001001, 7}, // 7比特编码 {0b011, 3}, // 3比特编码 {0b000010001, 9} // 9比特编码 }; uint8_t output[10]; // 提前分配足够大的缓冲区 uint32_t output_len = elias_gamma_concat(test_codes, 3, output); // 最终output数组应为:0x12, 0xC2, 0x20,output_len=3 return 0; }
效率优化与注意事项
- 减少循环次数:每次尽可能填充最多8位比特,避免逐位循环,适配STM32F4的Cortex-M4内核位运算效率
- 缓冲区预分配:若需处理4096个编码,可先遍历一次编码数组计算总比特数,再通过
(total_bits + 7)/8确定输出缓冲区大小,避免溢出 - 比特顺序校验:确保查找表中
code的比特存储顺序为高位在前,若你的查找表是低位在前存储,需调整位移动逻辑
内容的提问来源于stack exchange,提问作者user19402326
相关产品推荐
相关产品推荐

