У меня есть произвольное 8-битное двоичное число, например, 11101101
Мне нужно поменять все пары битов, например:
Перед заменой: 11-10-11-01
После замены: 11-01-11-10
Меня попросили в интервью!
У меня есть произвольное 8-битное двоичное число, например, 11101101
Мне нужно поменять все пары битов, например:
Перед заменой: 11-10-11-01
После замены: 11-01-11-10
Меня попросили в интервью!
В псевдокоде:
x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)
Он работает, обрабатывая младшие бит и высокие бит каждой битовой пары отдельно, а затем комбинируя результат:
x & 0b10101010
извлекает высокий бит из каждой пары, а затем >> 1
сдвигает его в положение с низким битом.(x & 0b01010101) << 1
извлекает младший бит из каждой пары и сдвигает его в положение с высоким битом.Поскольку не все языки позволяют писать бинарные литералы напрямую, вы можете записать их, например, в шестнадцатеричном формате:
Binary Hexadecimal Decimal 0b10101010 0xaa 170 0b01010101 0x55 85
10101010
и 01010101
).Пример для 16 бит (не действительный код):
short swap_bit_pair(short i) {
return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1));
}
b = (a & 170 >> 1) | (a & 85 << 1)
Самое элегантное и гибкое решение, как утверждают другие, - применять маску "гребенка" как к четному, так и к нечетному битам отдельно, а затем, смещая их влево и вправо соответственно в одном месте, чтобы объединить их с помощью побитового или.
Еще одно решение, о котором вы можете подумать, использует относительно небольшой размер вашего типа данных. Вы можете создать таблицу поиска из 256 значений, которая статически инициализируется значениями, которые вы хотите выводить на ваш вход:
const unsigned char lookup[] = { 0x02, 0x01, 0x03, 0x08, 0x0A, 0x09, 0x0B ...
Каждое значение помещается в массив для представления преобразования индекса. Поэтому, если вы это сделаете:
unsigned char out = lookup[ 0xAA ];
out
будет содержать 0x55
Это более громоздко и менее гибко, чем первый подход (что, если вы хотите перейти от 8 бит к 16?), но имеет подход, который будет значительно быстрее, если выполнить большое количество этих операций.
Предположим, что ваш номер num
.
Сначала найдите бит четной позиции: num & oxAAAAAAAA
Второй шаг найти бит нечетной позиции: num & ox55555555
Третий шаг изменения позиции нечетного положения для четного позиционирования бит и четного бита позиции в бит нечетного положения: Even = (num & oxAAAAAAAA)>>1
Odd = (num & 0x55555555)<<1
Последний шаг... result = Even | Odd
Результат печати
Сначала я бы назвал его "длинным", то есть несколькими очевидными, явными этапами, и использовал это, чтобы проверить, что модульные тесты, которые у меня были на месте, функционировали правильно, а затем переходят только к более эзотерическим решениям для обработки бит если бы у меня была потребность в производительности (и эта дополнительная производительность была достигнута указанными улучшениями)
Код для людей сначала, второй - компьютеры.