什么是0xaa和0x55在做什么?

时间:2017-05-11 19:17:43

标签: java python operators bit-manipulation

我试过谷歌搜索,但找不到任何可以理解的东西@。@ ... 有人可以用非专业人的术语解释这段代码中发生的事情吗?

这是“破解编码面试”一书中的一个问题。

“编写程序以尽可能少的指令交换整数中的奇数和偶数位(例如,交换位0和位1,交换位2和3,依此类推)。”

我这样做的方式并没有涉及位操作,因为我无法弄清楚%\ ...

def swap(n):

    b = bin(n)[2:]
    print(b)
    if len(b)%2 != 0:
        c = True
        b = b[0] + b

    pairs = wrap(b, 2)
    pairs = [i[::-1] for i in pairs]
    ans = ''.join(pairs)

    if c: ans = ans[1:]
    print(ans)

但是现在我正在看他们的答案而我并没有真正理解......(并没有帮助它不在Python中):

int swapOddEvenBits(int x) {
  return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );

3 个答案:

答案 0 :(得分:4)

让我们打破这一点。

return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );

首先,我们会看(x & 0xaaaaaaaa)。如果您将0xaaaaaaaa分解为比特级别,则最终得到1010 1010 1010 1010 1010 1010 1010 1010a,二进制为1010)。所以(x & 0xaaaaaaaa)说,只返回1中每个偶数位x。这称为位掩码。然后,你将它右移一个位置 - 这就是你如何使偶数数字切换位置(所以现在第二位占据第一位的位置,第四位占据第三位等)。

您使用(x & 0x55555555)执行相同操作 - 如果将其细分为位级别,则最终得到0101 0101 0101 0101 0101 0101 0101 0101(如5,二进制,{{1} })。这会掩盖0101中所有偶数位,并为您提供所有奇数位。然后,将所有位移到1.最后,使用xor)运算符组合两个位序列,这就是你的答案。

实施例: 我们将其转换为二进制文件并获取|。现在,我们执行1001 0010 0110 0100 1110 0110 1011 1101,然后获取

(x & 0xaaaaaaaa)

等于1001 0010 0110 0100 1110 0110 1011 1101 & 1010 1010 1010 1010 1010 1010 1010 1010。将其移至右侧,即可获得1000 0010 0010 0000 1010 0010 1010 1000

现在,执行0100 0001 0001 0000 0101 0001 0101 0100,然后获取

(x & 0x55555555)

等于1001 0010 0110 0100 1110 0110 1011 1101 & 0101 0101 0101 0101 0101 0101 0101 0101。将其移到左侧,即可获得0001 0000 0100 0100 0100 0100 0001 0101

最后,我们0010 0000 1000 1000 1000 1000 0010 1010。然后我们得到0100 0001 0001 0000 0101 0001 0101 0100 | 0010 0000 1000 1000 1000 1000 0010 1010,正如您所见,这是解决方案!

答案 1 :(得分:4)

转换为二进制,

0xaaaaaaaa == 0b10101010101010101010101010101010
0x55555555 == 0b01010101010101010101010101010101

这些数字在交替位置设置为0和1,所以当你&一个带有其中一个的数字时,它会每隔一位选择一次。

如果使用整数执行swapOddEvenBits过程,假设为0b01111100111101001111110000110010,我们得到

0xaaaaaaaa & 0b01111100111101001111110000110010 selects the following bits:
               0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1     # unselected bits are 0

0x55555555 & 0b01111100111101001111110000110010 selects the following bits:
                1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0

0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 gets shifted right:
 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1

and
 1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0 gets shifted left:
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0

and we | the results back together:
 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0
-------------------------------
10111100111110001111110000110001

答案 2 :(得分:1)

我们知道0xaa和0x55是十六进制表示形式。 此外,十六进制中的每个字符都使用4位表示

so,0xaa等于1010 1010(因为a = 1010二进制) 并且0x55等于0101 0101(因为5 = 0101,二进制)

将任何数字与其相加会返回给我们 数字,因此在解决诸如交换奇数之类的问题时很有用 甚至是数字。