按位求反后出现右移的意外结果

Isl*_*een 21 c bit-manipulation

我期望下面的代码将输出,10因为它(~port)等于10100101 So,当我们右移它时,4得到的0000101010。但是输出是250!为什么?

int main()
{
    uint8_t port = 0x5a;
    uint8_t result_8 =  (~port) >> 4;
    //result_8 = result_8 >> 4;

    printf("%i", result_8);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

ybu*_*ill 28

C 在对其进行操作之前uint8_t升级int为。所以:

  1. port被提升为有符号整数0x0000005a
  2. ~颠倒它的付出0xffffffa5
  3. 算术移位返回0xfffffffa
  4. 它被截断成uint8_t礼物0xfa == 250

要解决此问题,请截断临时结果:

uint8_t result_8 = (uint8_t)(~port) >> 4;
Run Code Online (Sandbox Code Playgroud)

遮盖它:

uint8_t result_8 = (~port & 0xff) >> 4;
Run Code Online (Sandbox Code Playgroud)

或xor(感谢@Nayuki!):

uint8_t result_8 = (port ^ 0xff) >> 4;
Run Code Online (Sandbox Code Playgroud)

  • uint8_t很可能是系统上unsigned char的同义词。促销规则适用于所有小于“ int”的整数类型。 (13认同)
  • 或者明确地只翻转低8位:`result =(port ^ 0xFF)>> 4;` (7认同)
  • @TomášZato:是的。参见https://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotions (2认同)