我试图以一种可移植的方式将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/