Мне интересно, как я могу поменять местами интервал битов с числа X на число Y, используя побитовые операции.
Так, например, у меня есть номер:
X = 00000000
Y = 00111111
positionStart, positionEnd
И я хочу заменить биты [positionStart, positionEnd] в X битами из Y в той же позиции.
Если у вас есть маска m
это указывает биты, которые вы хотите переместить или поменять местами, вы можете переместить их так:
x = x ^ ((x ^ y) & m)
Или поменяйте их местами так:
t = (x ^ y) & m
x ^= t
y ^= t
Это может быть объяснено как принятие битовой разницы между x
а также y
только в местах где m
установлено. Тогда XORing x
с этим переворачивает биты в x
где x
а также y
разные (и m
установлено), поэтому он меняет эти биты x
на кусочки y
, То же самое относится и к y
,
Маска может быть создана как
m = (2 << end) - (1 << start)
Сначала создайте маску (это предполагает Python-подобное индексирование от наименее до наиболее значимого, начиная с нуля и не включая верхний индекс):
M = (1 << positionEnd) - 1) & ~((1 << positionStart) - 1)
Если вы хотите заменить биты в X
с теми, кто в Y
:
X = (X & ~M) | (Y & M)
Если вы хотите поменяться местами, вы можете использовать третью переменную или сделать что-то вроде маскируемой XOR трюк:
X = (X & ~M) | ((X ^ Y) & M)
Y = (Y & ~M) | ((X ^ Y) & M)
X = (X & ~M) | ((X ^ Y) & M)