Операция 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;