0xaa和0x55在做什么?

2024-09-27 04:24:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用谷歌搜索,但找不到任何可以理解的东西。。。 有人能用外行的话解释一下这段代码里发生了什么吗?

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

编写一个程序,用尽可能少的指令交换整数中的奇偶位(例如,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) );

Tags: 代码程序编码ifdef方式指令整数
3条回答

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

所以,0xaa相当于1010 1010(因为,a=1010,二进制) 0x55相当于0101 0101(因为,5=0101二进制)

将任意数字与它们相加,返回 因此在解决像交换奇数这样的问题时很有用 甚至数字。

让我们把这个分解。

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

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

你对(x & 0x55555555)做同样的事情-如果你把它分解到位级别,你最终得到0101 0101 0101 0101 0101 0101 0101 0101(因为5,在二进制中,是0101)。这将屏蔽x中的所有偶数位,并为您提供所有奇数位。然后,将所有位左移1。最后,使用or|)运算符组合这两个位序列,这就是您的答案。

示例: 我们乘2456086205吧。我们把它转换成二进制,得到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。然后我们得到0110 0001 1001 1000 1101 1001 0111 1110,正如您所看到的,这就是解决方案!

转换成二进制

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

相关问题 更多 >

    热门问题