Каждые четыре бита представляет собой шестнадцатеричную цифру следующим образом:
0000 0 1000 8
0001 1 1001 9
0010 2 1010 A
0011 3 1011 B
0100 4 1100 C
0101 5 1101 D
0110 6 1110 E
0111 7 1111 F
Так, например, 0x1234
будет 0001 0010 0011 01002
.
Для ваших конкретных примеров:
0xaaaaaaaa = 1010 1010 ... 1010
0x55555555 = 0101 0101 ... 0101
Причина, почему решение может использовать эти два значения в том, что, если вы и значение с 0xaaaaaaaa
, вы получите только нечетные биты (отсчет слева), который затем можно сдвинуть вправо, чтобы переместить их на четные позиции бит.
Аналогичным образом, если вы И с 0x55555555
, вы получите только четные биты, которые вы можете сдвинуть влево, чтобы переместить их в позиции нечетного бита.
Тогда вы можете просто ИЛИ эти два значения вместе, и биты были заменены.
Например, давайте начнем с 16-битовым значением abcdefghijklmnop
(каждая буква будучи немного, и с нулевой бит быть .
, чтобы сделать его более удобным для чтения):
abcdefghijklmnop abcdefghijklmnop
AND 1.1.1.1.1.1.1.1. AND .1.1.1.1.1.1.1.1
= a.c.e.g.i.k.m.o. = .b.d.f.h.j.l.n.p
>>1 = .a.c.e.g.i.k.m.o <<1 = b.d.f.h.j.l.n.p.
\___________ ___________/
\ /
.a.c.e.g.i.k.m.o
OR b.d.f.h.j.l.n.p.
= badcfehgjilknmpo
Таким образом, каждая группа из двух битов имеет поменялись местами. В C, это было бы что-то вроде:
val = ((val & 0xAAAAAAAA) >> 1) | ((val & 0x55555555) << 1);
, но, если это классная работа какого-то описания, я предлагаю вам работать это сами, делая отдельные операции.
Для подробного объяснения побитовых операторов, которые позволяют это сделать, см. this excellent answer here.
Вы можете просто использовать шестнадцатеричный в бинарный конвертер онлайн. http://www.binaryhexconverter.com/hex-to-binary-converter – Tholle
@tholle спасибо! – user21