如何在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
相关产品推荐
相关产品推荐

