将unsigned解释为已签名

Sve*_*-de 7 c++ embedded static-cast reinterpret-cast

我正在研究嵌入式平台(ARM),在处理位模式时必须小心.让我们假装这条线超出了我的影响力:

uint8_t foo = 0xCE;          // 0b11001110
Run Code Online (Sandbox Code Playgroud)

解释为无符号,这将是206.但实际上它是签名的,因此类似于-50.如何继续使用此值作为签名?

int8_t bar = foo;            // doesn't work
Run Code Online (Sandbox Code Playgroud)

两者都没有(导致所有输入值的0x10或0x00)

int8_t bar = static_cast<int8_t>(foo);
int8_t bar = reinterpret_cast<int8_t&>(foo);
Run Code Online (Sandbox Code Playgroud)

我只是希望这些位保持不变,即. (bar == 0xCE)

反之亦然我感兴趣的是如何将代表负数的位模式转换为无符号变量而不会弄乱位模式.我正在使用GCC.

Ker*_* SB 8

以下对我来说很好,因为它应该如评论所说,这是实现定义的:

int x = (signed char)(foo);
Run Code Online (Sandbox Code Playgroud)

在C++中,您还可以说:

int x = static_cast<signed char>(foo);
Run Code Online (Sandbox Code Playgroud)

请注意,促销始终会在重新解释位模式之前尝试保留该.因此,您首先必须转换为与无符号类型相同大小的签名类型,以强制进行签名重新解释.

(当我尝试将chars作为十六进制数字对打印时,我通常面临相反的问题.)

  • 如果数字不能表示为signed,则unsigned to signed是实现定义的.签名为无符号变为"与源整数一致的最小无符号整数(模2 ^ n)." 在二进制补码表示中,这只保持相同的位模式.请参见4.7积分转换. (3认同)

Goz*_*Goz 5

uint8_t foo = 0xCE;          // 0b11001110
int8_t bar;
memcpy( &bar, &foo, 1 );
Run Code Online (Sandbox Code Playgroud)

它甚至还有额外的好处,99%的编译器将完全优化对memcpy的调用...