Я хочу вычислить обратную маску для знака без знака - PullRequest
6 голосов
/ 04 ноября 2011

Я хотел бы вычислить обратную маску для неподписанного символа char.meaning, если исходная маска 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;
}

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

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

Ответы [ 5 ]

6 голосов
/ 04 ноября 2011

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

inverse_mask = ~mask;
6 голосов
/ 04 ноября 2011

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

uint8_t mask = 0x03;
uint8_t inverse_mask = ~mask;
1 голос
/ 04 ноября 2011

Есть много способов сделать это.

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

x = 01110110

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

y = 10001001

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

  • Каждый бит y не совпадает с соответствующим битом в x
    • Эта операция выполняется в C следующим образом: y = ~x;
    • В качестве альтернативы мы знаем, что один бит xor 1 дает не этот бит, поэтому y = x^0xFF;
  • Сумма любого бита плюс его не 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 & mask) ^ mask;

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

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

1 голос
/ 04 ноября 2011

Ваша функция 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 & mask) ^ mask;
}
1 голос
/ 04 ноября 2011

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

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