我有一个任意 8位二进制数字,例如11101101
我必须交换所有这些位,如:
在交换之前:11-10-11-01
交换后:11-01-11-10
我在接受采访时被问到这个问题!
答案 0 :(得分:32)
在伪代码中:
x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)
它的工作原理是分别处理每个位对的低位和高位,然后组合结果:
x & 0b10101010
从每对中提取高位,然后>> 1
将其移至低位位置。(x & 0b01010101) << 1
从每对中提取低位并将其移位到高位位置。由于并非所有语言都允许您直接编写二进制文字,因此可以将其编写为十六进制:
Binary Hexadecimal Decimal 0b10101010 0xaa 170 0b01010101 0x55 85
答案 1 :(得分:5)
10101010
和01010101
)。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” - 也就是说在几个明显的显式阶段中,并使用它来验证我所使用的单元测试是否正常运行,然后只转向更深奥的位操作解决方案如果我需要表现(并且通过所述改进提供额外的表现)
人员代码,计算机第二。