Побитовая замена битов в двух числах

Мне интересно, как я могу поменять местами интервал битов с числа X на число Y, используя побитовые операции.

Так, например, у меня есть номер:

X = 00000000
Y = 00111111

positionStart, positionEnd

И я хочу заменить биты [positionStart, positionEnd] в X битами из Y в той же позиции.

3

Решение

Если у вас есть маска 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)
2

Другие решения

Сначала создайте маску (это предполагает 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)
1

По вопросам рекламы [email protected]