将n字节整数拆分为单字节的可移植方式

时间:2019-01-18 14:19:42

标签: c bit-manipulation portability

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

要做到这一点,我可以轻松地使用位掩码和移位来获得所需的内容。但是,我希望这是可移植的,并且可以在大小不一的字节序上使用,而且还使其适用于不丢弃位而是rotate through carry(屏蔽可以去除多余的位吗?)的平台。

示例代码:

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位整数或更多位数的任何平台上使用。我不知道这是否正确。

1 个答案:

答案 0 :(得分:7)

您提供的代码是最可移植的方式。您将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 bits.h