首页 > 解决方案 > 将 n 字节整数拆分为单个字节的便携式方法

问题描述

问题很简单:取一个 32 位或 64 位整数并将其拆分以通过(通常)1 字节接口(如 uart、spi 或 i2c)发送。

为此,我可以轻松地使用位掩码和移位来获得我想要的。但是,我希望它是可移植的,可以在大端和小端上工作,但也使它适用于不丢弃位但通过进位旋转的平台(屏蔽可以去除多余的位,对吗?)。

示例代码:

uint32_t value;
uint8_t buffer[4];
buffer[0] = (value >> 24) & 0xFF;
buffer[1] = (value >> 16) & 0xFF;
buffer[2] = (value >> 8) & 0xFF;
buffer[3] = value & 0xFF;

我想保证这适用于任何支持 32 位整数或更多的平台。我不知道这是否正确。

标签: cbit-manipulationportability

解决方案


您提供的代码是最便携的方式。您将一个 32 位宽度的无符号整数值转换为一个正好为 8 位宽度的无符号整数值数组。数组中的结果字节按buffer大端顺序排列。

不需要掩蔽。从C11 6.5.7p5 开始

E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 具有无符号类型或 E1 具有
有符号类型和非负值,则结果的值是
E1 / 2^E2 的商的整数部分。

并且转换为具有 8 位宽度的整数(到值)等于屏蔽 8 位。所以(result >> 24) & 0xff等于(uint8_t)(result >> 24)(值)。当您分配给uint8_t变量时,不需要屏蔽。无论如何,我会安全地假设它会被一个理智的编译器优化出来。

我可以建议看一下我记得的一个实现,我猜它已经以一种非常安全的方式实现了所有可能的拆分和组合固定宽度整数的变体,从字节和返回到 64 位,即gpsd 位.h


推荐阅读