Перемещение бита в байте с использованием битового поля или побитовых операторов

Есть ли элегантный способ перемещения бита в байте (или word / long). Для простоты давайте использовать простой 8-битный байт и всего один бит для перемещения внутри байта.

Дан номер бита, основанный на 0–7 от младшего бита до наибольшего бита (или битов 1 -8, если хотите), я бы хотел немного переместиться из одной позиции в другую:

7654 3210 <bit position
0101 1010 <some binary value
--x- --y- <move bit from x to y
0111 0100 <new value with x moved to y and intervening bits shifted left

Итак, x в позиции бита 5 перемещается в y в позиции бита 1, биты 0,6,7 остаются неизменными. Биты 2, 3, 4 сдвигаются влево, чтобы «освободить место» для бита, перемещенного с 5 на 2. Это просто пример.

Важно, чтобы бит перемещался, а не переставлялся со своей целью. Существует множество примеров битов, которые меняются местами, но это довольно тривиально.

В идеале решение должно было бы использовать простые побитовые и побитовые операторы. Предположим, что независимый от языка, битовый простой AND / OR / XOR, NOT, SHIFT влево / вправо / ROTATE или аналогичные инструкции подойдут в любой комбинации, плюс любой другой базовый арифметический оператор, например: mod, сложение / вычитание и т. Д. Даже работающие псевдо- код будет в порядке. В качестве альтернативы, вероятно, будет проще использовать битовый массив или структуру типа битового поля.

В дополнение к фактическому перемещению битов я хотел бы найти способ:

  • Перемещать любой бит вверх или вниз.
  • Укажите источник / назначение битового номера в любом удобном формате: например: 6> 2 подразумевает сдвиг вниз, 3> 7 сдвиг вверх или стартовый бит +/- смещение: 6-4 или 3 + 4, или битовый взвешенный: бит 6 = 64 на бит 3 = 8.
  • Возможно расширение от байта до беззнакового int, long и т. Д.
  • (В идеале, с возможностью расширения к более чем одному биту за раз, возможно, к соседним битам, если проще)

Производительность не является серьезной проблемой, но что-то элегантное, вероятно, будет достаточно быстрым.

Мой собственный индивидуальный подход состоял бы в том, чтобы идентифицировать источник и целевые битовые позиции, решить, сдвинуть вверх или вниз, взять сдвинутую копию,замаскируйте статические биты и найдите исходный бит, объедините статические и сдвинутые биты и каким-то образом установите / очистите целевой бит. Однако, хотя теория кажется хорошей, элегантная реализация мне не по силам.

Я понимаю, что предварительно скомпилированная таблица поиска может быть построена для байта, но если ее нужно расширить до целых / длинных, это было бы непрактично для меня. .

Любая помощь приветствуется. Заранее спасибо.

5
задан andora 21 June 2011 в 21:15
поделиться