C 如何检索存储在无符号变量中的有符号值

C 如何检索存储在无符号变量中的有符号值,c,integer,embedded,type-conversion,C,Integer,Embedded,Type Conversion,我在一个无符号uint8_t变量中存储了一个有符号的8位值(2的补码)。 这是因为该值是通过spi接口从外部外围设备读取的,例如: uint8\u t返回值=读取spi(uint8\u t寄存器地址) 外设的数据表显示,该特定地址包含2的补码值,因此返回值内的位模式应为有符号8位值 我知道检索有符号值的明显方法:去掉符号位,如果是负倒转位,加1,乘以-1 我想知道是否有更优雅的方式。在C语言中,你可以通过联合体键入双关语 union foo { uint8_t ui; int8_

我在一个无符号uint8_t变量中存储了一个有符号的8位值(2的补码)。 这是因为该值是通过spi接口从外部外围设备读取的,例如:

uint8\u t返回值=读取spi(uint8\u t寄存器地址)

外设的数据表显示,该特定地址包含2的补码值,因此返回值内的位模式应为有符号8位值

我知道检索有符号值的明显方法:去掉符号位,如果是负倒转位,加1,乘以-1


我想知道是否有更优雅的方式。

在C语言中,你可以通过
联合体键入双关语

union foo
{
    uint8_t ui;
    int8_t i;
} f;

设置
f.ui=return\u value
然后使用
f.i
在C中读回有符号的值,您可以通过
联合输入pun

union foo
{
    uint8_t ui;
    int8_t i;
} f;

设置
f.ui=return\u value
,然后使用
f.i

读取带符号的值如果您使用的是两位补码系统,您可以执行以下操作:

int8_t result = return_value;  // or assign the from function directly
严格来说,当值为负值时,行为由实施定义(N1570,6.3.1.3):

  • 当整数类型的值转换为除_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变
  • 否则,新类型已签名,且无法在其中表示值;要么结果是实现定义的,要么引发实现定义的信号

  • 在实践中,它只是起作用
    intN\u t
    类型保证是2的补码,并且没有填充位。典型的现代机器不需要对无符号到有符号的赋值执行任何额外的操作,只需复制位即可。如果您想确定,请查看您的编译器手册。

    如果您使用的是2的补码系统,您可以执行以下操作:

    int8_t result = return_value;  // or assign the from function directly
    
    严格来说,当值为负值时,行为由实施定义(N1570,6.3.1.3):

  • 当整数类型的值转换为除_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变
  • 否则,新类型已签名,且无法在其中表示值;要么结果是实现定义的,要么引发实现定义的信号

  • 在实践中,它只是起作用
    intN\u t
    类型保证是2的补码,并且没有填充位。典型的现代机器不需要对无符号到有符号的赋值执行任何额外的操作,只需复制位即可。如果您想确定,请查看编译器手册。

    如果寄存器中的值是有符号值,则只需将其作为有符号值处理,无需进行转换,简单的强制转换就足够了。用于读取外围寄存器的通用例程以允许读入任何值的方式写入。这类似于缓冲区读取,其中缓冲区定义为泛型字符,然后分配给结构或其他内容。您所要做的只是:
    int8\u t MyVar=(int8\u t)read\u spi(RegAddr)int8_t MyVar=(int8_t)读取spi(RegAddr);我同意这可能会起作用,正如user694733所说,但从任何角度来看,这不是类型转换吗?为什么不是类型转换呢?cast操作符就在那里:
    (int8\u t)
    。为什么这很重要?此转换定义明确、安全且可移植。检索带符号值不需要算术运算-它只是对同一位模式的重新解释-将其指定给带符号类型(带或不带显式强制转换)如果寄存器中的值是有符号值,则只需将其作为有符号值处理,无需进行转换,一个简单的转换就足够了。用于读取外围寄存器的通用例程以允许读入任何值的方式写入。这类似于缓冲区读取,其中缓冲区定义为泛型字符,然后分配给结构或其他内容。您所要做的只是:
    int8\u t MyVar=(int8\u t)read\u spi(RegAddr)int8_t MyVar=(int8_t)读取spi(RegAddr);我同意这可能会起作用,正如user694733所说,但从任何角度来看,这不是类型转换吗?为什么不是类型转换呢?cast操作符就在那里:
    (int8\u t)
    。为什么这很重要?此转换定义明确、安全且可移植。检索有符号值不需要算术运算-它只是对同一位模式的重新解释-将其分配给有符号类型(带或不带显式强制转换)并继续。字符类型上不能有填充位(C标准明确禁止),stdint类型上也不能有填充位-它们保证是2的补码。字符类型上不能有填充位(C标准明确禁止),stdint类型上也不能有填充位-它们保证是2的补码。你的意思是“pun”而不是“prune”Oops。今晚我会让我2岁的孩子给我朗读。让我们重新学习英语!我喜欢“类型修剪”这个词——我要找到它的用途!;-)这对我来说甚至是有意义的,我想它会删掉符号:)你是说“双关语”而不是“删掉”哦。今晚我会让我2岁的孩子给我朗读。让我们重新学习英语!我喜欢“类型修剪”这个词——我要找到它的用途!;-)这对我来说甚至是有意义的,我想这会删掉标志:)