交换字节中的一对比特

时间:2010-09-21 08:10:21

标签: bit-manipulation

我有一个任意 8位二进制数字,例如11101101

我必须交换所有这些位,如:

在交换之前:11-10-11-01 交换后:11-01-11-10

我在接受采访时被问到这个问题!

6 个答案:

答案 0 :(得分:32)

在伪代码中:

x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)

它的工作原理是分别处理每个位对的低位和高位,然后组合结果:

  • 表达式x & 0b10101010从每对中提取高位,然后>> 1将其移至低位位置。
  • 类似地,表达式(x & 0b01010101) << 1从每对中提取低位并将其移位到高位位置。
  • 然后使用按位OR组合这两部分。

由于并非所有语言都允许您直接编写二进制文字,因此可以将其编写为十六进制:

Binary        Hexadecimal  Decimal 
0b10101010    0xaa         170
0b01010101    0x55         85

答案 1 :(得分:5)

  1. 制作两个位掩码,一个包含所有偶数位,另一个包含不均匀位(1010101001010101)。
  2. 使用按位 - 并将输入过滤为两个数字,一个将所有偶数位置零,另一个将所有不均匀位置零。
  3. 将仅包含偶数位的数字向左移一位,将另一位向右移一位
  4. 按位使用 - 或将它们组合在一起。
  5. 16位(非实际代码)的示例:

    short swap_bit_pair(short i) {
        return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1));
    }
    

答案 2 :(得分:0)

b = (a & 170 >> 1) | (a & 85 << 1)

答案 3 :(得分:0)

正如其他人所说的那样,最优雅和灵活的解决方案是单独对偶数和奇数位应用“梳状”掩码,然后将它们分别向左和向右移动一个位置以使用按位或者组合它们。

您可能想要考虑的另一个解决方案是利用相对较小的数据类型。您可以创建256个值的查找表,这些值静态初始化为您想要输出到输入的值:

const unsigned char lookup[] = { 0x02, 0x01, 0x03, 0x08, 0x0A, 0x09, 0x0B ...

每个值都放在数组中以表示索引的转换。所以,如果你这样做:

unsigned char out = lookup[ 0xAA ];

out将包含0x55

这比第一种方法更麻烦且更不灵活(如果你想从8位移动到16位怎么办?)但是如果执行大量的这些操作,它的确会更快。

答案 4 :(得分:0)

假设您的号码为num

首先找到偶数位位:
num & oxAAAAAAAA

第二步找到奇数位位:
num & ox55555555

第3步将奇数位置改为偶数位和偶数位位到奇数位位:
Even = (num & oxAAAAAAAA)>>1
Odd = (num & 0x55555555)<<1

最后一步...... result = Even | Odd

打印结果

答案 5 :(得分:-5)

我首先将它编写为“longhand” - 也就是说在几个明显的显式阶段中,并使用它来验证我所使用的单元测试是否正常运行,然后只转向更深奥的位操作解决方案如果我需要表现(并且通过所述改进提供额外的表现)

人员代码,计算机第二。