我试图以一种可移植的方式将uint8_t重新解释为int8_t(并再次返回)。我正好通过存储在uint8_t缓冲区中的串行 channel 接收数据,但是一旦知道了它是哪种数据包,就需要将某些字节解释为二进制补码,而将其他字节解释为无符号。

我知道这将适用于许多编译器:

int8_t i8;
uint8_t u8 = 0x94;

i8 = (int8_t)u8;

但是不能保证在u8> 127时工作,因为不确定将大于INT8_MAX的值强制转换为int8_t(我认为)。

我能想到的最好的是
int8_t i8;
uint8_t u8;

i8 = (u8 > INT8_MAX) ? (int8_t)(-(256-u8)):(int8_t)u8;

这应该总是有效的,因为减法总是会导致int的自动提升,并且绝不依赖于基础表示。它隐式地强制对大于INT8_MAX的值进行二进制补码解释。

有没有更好的方法(或标准的MACRO)来做到这一点?

最佳答案

如果定义了int8_t(通过<stdint.h>),则可以保证是两个补码(通过C 2018 7.20.1.1)。

通过将uint8_t u8中的值复制到int8_t i8中,可以将其重新解释为二进制补码值。 (好的编译器会对此进行优化,以简单地将memcpy(&i8, &u8, sizeof i8);用作两个的补码值,而无需调用u8。)

关于c - uint8_t的可移植重新解释为int8_t并强制二进制补码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54582843/

10-12 16:07