Islam Abdeen
Islam Abdeen

Reputation: 539

Unexpected result with right shift after bitwise negation

I expected that below code will output 10 because (~port) equal to 10100101 So, when we right shift it by 4 we get 00001010 which is 10. But the output is 250! Why?

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

    printf("%i", result_8);

    return 0;
}

Upvotes: 24

Views: 910

Answers (1)

Yakov Galka
Yakov Galka

Reputation: 72449

C promotes uint8_t to int before doing operations on it. So:

  1. port is promoted to signed integer 0x0000005a.
  2. ~ inverts it giving 0xffffffa5.
  3. An arithmetic shift returns 0xfffffffa.
  4. It's truncated back into a uint8_t giving 0xfa == 250.

To fix that, either truncate the temporary result:

uint8_t result_8 = (uint8_t)(~port) >> 4;

mask it:

uint8_t result_8 = (~port & 0xff) >> 4;

or xor it (thanks @Nayuki!):

uint8_t result_8 = (port ^ 0xff) >> 4;

Upvotes: 31

Related Questions