Как инвертировать последние биты Y и получить положительное число? - PullRequest
1 голос
/ 23 апреля 2020

Мне нужно инвертировать биты Y справа налево, после удаления Z справа налево.

x и y = 2; 16 в двоичном коде - 10000. Удалив последние 2 бита (z), мы получим 100. Теперь мне нужно обратить вспять последние 2 ноля, чтобы результат был 3 в десятичном виде. Не могли бы вы помочь мне? Я не могу извлечь только последние 2 (y), чтобы инвертировать их, а затем добавить их в оставшийся бит.

int x = 16; // 10000
int y = 2;
int z= 2;
x = x>>z;
// x = 100
//inverse the last 2(y), 00 -> 11;
//print 3(11)

1 Ответ

3 голосов
/ 23 апреля 2020

Операция exclusive или (XOR) между целевым битом и 1 инвертирует целевой бит; Более того, вы можете выполнить эту операцию с любым набором битов в данной переменной (64-32- и 16-битный int или байт), используя битовую маску , чтобы указать, какие биты переворачивать (настройка эти биты в маске) ​​- остальные биты (т. е. биты с 0 в маске) ​​останутся без изменений.

Вы также можете использовать битовую маску с оператором bitwise AND для очистить любые указанные c биты; в этом случае эти биты, соответствующие 1 в маске, останутся без изменений , тогда как биты, соответствующие 0 в маске, будут очищены .

Таким образом, последние два бита можно перевернуть с помощью XOR для цели со значением 3 (которое ...00011 в двоичном виде); затем вы можете очистить все остальные биты с помощью оператора & (в этом случае маска будет такой же).

Таким образом, этот код будет делать то, что вы хотите:

int x = 16; // 10000
int y = 2;
int z= 2;
x = x >> z;// Shifts out (removes) the low 'z' bits
x = x ^ 3; // Flips the last two bits ("^" is the XOR operator)
x = x & 3; // Clears all BUT the last two bits

Или, более кратко:

x = ( (x >> z) ^ 3 ) & 3;

Примечание. Если вы хотите изменить младшие 2 биты на переменное количество битов (т.е. на z, как у вас есть с оператором сдвига), то вы можете создать битовую маску, зная, что 2 z - 1 будет числовым значением этой маски. Вы можете получить это значение в переменную mask, сместив влево число 1 на z (одно смещение влево равно , обычно , эквивалентно умножению на 2, для малых положительные числа), затем вычитая 1:

int mask = (1 << z ) - 1;

Затем вы можете использовать mask вместо фиксированного значения 3 в приведенном выше коде:

x = ( (x >> z) ^ mask ) & mask;
...