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

如何在C++中将两个uint16_t压缩为3字节(各占12位)用于CAN报文?

将两个uint16_t压缩到3字节的C++实现

核心逻辑

要实现两个uint16_t各占12位存入3字节,步骤如下:

  • 对每个输入值保留低12位(丢弃高4位,满足你“高于12位无关紧要”的需求)
  • 将第一个值的12位放到24位空间的高12位,第二个值的12位放到低12位
  • 把合并后的24位数值拆分为3个字节,根据CAN报文要求选择大端/小端字节序

代码实现

#include <cstdint> // 引入标准固定宽度整数类型

// 输入:两个uint16_t数值,输出:存储压缩结果的3字节数组
void compressTo3Bytes(uint16_t num1, uint16_t num2, uint8_t out[3]) {
    // 1. 截断每个数值到低12位
    uint16_t truncatedNum1 = num1 & 0x0FFF; // 0x0FFF是12位全1的掩码,过滤高4位
    uint16_t truncatedNum2 = num2 & 0x0FFF;

    // 2. 合并为24位数值:第一个数左移12位,与第二个数按位或
    uint32_t combined = (static_cast<uint32_t>(truncatedNum1) << 12) | truncatedNum2;

    // 3. 拆分到3字节(采用CAN常用的大端字节序:高位字节在前)
    out[0] = static_cast<uint8_t>((combined >> 16) & 0xFF); // 24位的最高8位
    out[1] = static_cast<uint8_t>((combined >> 8) & 0xFF);  // 中间8位
    out[2] = static_cast<uint8_t>(combined & 0xFF);        // 最低8位

    // 如果需要小端字节序,替换为以下代码:
    // out[0] = static_cast<uint8_t>(combined & 0xFF);
    // out[1] = static_cast<uint8_t>((combined >> 8) & 0xFF);
    // out[2] = static_cast<uint8_t>((combined >> 16) & 0xFF);
}

代码说明

  • 使用uint8_t/uint16_t/uint32_t是C++标准固定宽度类型,避免不同平台的整数长度差异
  • 0x0FFF掩码确保只保留输入值的低12位,自动丢弃无关的高4位
  • 合并时先将truncatedNum1转为uint32_t再左移,防止16位整数左移溢出
  • 字节序选择需匹配你的CAN报文协议,大部分CAN设备默认使用大端字节序

调用示例

#include <iostream>

int main() {
    uint16_t val1 = 0x1234; // 截断后为0x0234
    uint16_t val2 = 0x5678; // 截断后为0x0678
    uint8_t canData[3];

    compressTo3Bytes(val1, val2, canData);

    // 大端模式下输出字节:0x02, 0x34, 0x78
    std::printf("Compressed bytes: 0x%02X, 0x%02X, 0x%02X\n", canData[0], canData[1], canData[2]);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:52:25