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

如何将不同长度比特序列转换为字节数组(STM32F405+C环境)

解决方案

核心实现思路

用两个状态变量跟踪拼接过程,适配字节为最小操作单位的限制:

  • current_byte:正在填充的未完成字节(uint8_t类型)
  • bit_count:当前字节已填充的比特数(范围0~7)

逐个处理每个Elias Gamma编码符号时,按以下逻辑操作:

  1. 把编码符号的比特位(按高位在前的顺序)填充到current_byte的剩余空间
  2. 若填充后bit_count达到8,将current_byte写入输出数组,重置状态变量
  3. 若编码符号还有剩余比特未填充,重复上述步骤直到整个符号处理完毕
  4. 所有符号处理完成后,若仍有不足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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:56:33