Я хочу вычислить обратную маску для символа без знака

#c #bit-manipulation #bitmask

#c #битовая манипуляция #битовая маска

Вопрос:

Я хотел бы вычислить обратную маску для символа без знака. это означает, что если исходная маска 0xc0, обратная маска должна быть 0x3f. то есть все биты должны быть перевернуты или инвертированы.Я пробовал ниже, но, похоже, не работает.

 int flipBit(int x, unsigned char position)
{
  int mask = 1 << position;
  return x ^ mask;
}

int main(int argc , char* argv[])
{
        uint8_t mask = 0x03;
        uint8_t inverse_mask = 0;
        uint8_t temp = 0;
        int loop = 0;

        for (loop = 0; loop < 8 ; loop   )
        {
                temp = flipBit(mask,loop);
                inverse_mask |= temp;
        }
        printf("mask 0x%x inv mask 0x%x n",mask,inverse_mask);
        return 0;
}
  

Результаты, которые я получаю, —
mask 0x3 inv mask 0xff

Кажется, я не могу найти ошибку в своем коде.

Ответ №1:

Почему вы не можете просто сделать это:

 uint8_t mask = 0x03;
uint8_t inverse_mask = ~mask;
  

Ответ №2:

Используйте оператор ~ (побитовый-нет).

 inverse_mask = ~mask;
  

Комментарии:

1. Чтобы быть семантическим, ~ это побитовый оператор not, который является унарным оператором.

2. Спасибо. Я редактировал только это в то же время, когда вы опубликовали это.

Ответ №3:

Есть много способов, которыми вы можете это сделать.

Допустим, у вас есть это двоичное значение:

 x = 01110110
  

Как человек, мы можем определить его «обратный» как:

 y = 10001001
  

Теперь давайте посмотрим на его свойства:

  • Каждый бит y — это не соответствующий бит в x
    • Эта операция выполняется на C следующим образом: y = ~x;
    • В качестве альтернативы, мы знаем, что один бит xor 1 не дает этого бита, поэтому y = x^0xFF;
  • Сумма любого бита плюс его not равна 1, без переноса. Поэтому y x == 0xFF
    • Поэтому, y = 0xFF-x;

Что касается того, почему ваша программа не работает, давайте проследим за циклом:

 loop: 0
  mask:         0000 0011
  temp:         0000 0010
  inverse_mask: 0000 0010
loop: 1
  mask          0000 0011
  temp          0000 0001
  inverse_mask: 0000 0011
inverse_mask eventually: 0xFF
  

Вы могли видеть проблему в самом первом цикле: вы получили единицу на втором месте inverse_mask , которой у вас не должно быть.

Если вы хотели temp сохранить только бит, который был перевернут, вы должны были записать вместо flibBit :

 return x ^ mask;
  

эта строка:

 return (x amp; mask) ^ mask;
  

Чтобы вы сначала изолировали бит, а затем перевернули его.

Я объяснил, чтобы вы узнали об ошибке в своей программе, вам все равно следует использовать один из методов, которые я упомянул в первую очередь.

Ответ №4:

Это очень просто сделать с помощью XOR.

 uint8_t mask = 0x03;
uint8_t inverse_mask = mask ^ 0xFF;
  

Ответ №5:

Ваша функция flipBit должна возвращать не более одного бита только для того, чтобы ваш код работал:

 0x03 ^ 0x01 = 0x02
0x03 ^ 0x02 = 0x01
0x03 ^ 0x04 = 0x07
0x03 ^ 0x08 = 0x0b
0x03 ^ 0x10 = 0x13
0x03 ^ 0x20 = 0x23
0x03 ^ 0x40 = 0x43
0x03 ^ 0x80 = 0x83
0x2 ^ 0x1 ^ 0x7 ^ 0xb ^ 0x13 ^ 0x23 ^ 0x43 ^ 0x83 = 0xff

int flipBit(uint8_t x, unsigned char position)
{
  int mask = 1 << position;
  return (x amp; mask) ^ mask;
}