我有一个带符号的8位值(以二进制补码)存储在无符号uint8_t变量中。 发生这种情况是因为通过spi接口从外部外设读取值,如:
uint8_t return_value = read_spi(uint8_t register_address)
外围设备的数据表说该特定地址包含二进制补码值,因此return_value内的位模式应为带符号的8位值。
我知道检索有符号值的明显方法:剥离符号位,如果是负翻转位,则加1,乘以-1。
我想知道是否有更优雅的方式。
答案 0 :(得分:4)
在C中,您可以通过union
输入双关语。
union foo
{
uint8_t ui;
int8_t i;
} f;
设置f.ui = return_value
,然后使用f.i
回读签名值。
答案 1 :(得分:4)
如果您使用的是二进制补码系统,您可以这样做:
int8_t result = return_value; // or assign the from function directly
严格来说,当值为负时,行为是实现定义(N1570,6.3.1.3):
- 当整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以用新类型表示,则它将保持不变。
- ...
- 否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。
醇>
在实践中,它只是起作用; intN_t
类型保证是两个补码,没有填充位。典型的现代机器不需要对无符号到有符号赋值执行任何额外操作,只需复制这些位。如果您想确定,请查看编译器手册。