Неожиданный результат с правым сдвигом после побитового отрицания - PullRequest
21 голосов
/ 15 апреля 2019

Я ожидал, что приведенный ниже код выдаст 10, потому что (~port) равно 10100101 Итак, когда мы сместим вправо на 4, мы получим 00001010, что равно 10.Но на выходе получается 250!Почему?

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

    printf("%i", result_8);

    return 0;
}

1 Ответ

28 голосов
/ 15 апреля 2019

C повышает uint8_t до int перед выполнением операций с ним. Итак:

  1. port повышается до целого числа со знаком 0x0000005a.
  2. ~ инвертирует, давая 0xffffffa5.
  3. Арифметический сдвиг возвращает 0xfffffffa.
  4. Он усекается обратно в uint8_t, давая 0xfa == 250.

Чтобы это исправить, либо обрежьте временный результат:

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

замаскируйте его:

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

или еще раз (спасибо @Nayuki!):

uint8_t result_8 = (port ^ 0xff) >> 4;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...