写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。
#define SwapIntBit(n) (((n) & 0x55555555) << 1 | ((n) & 0xaaaaaaaa) >> 1)
交换奇偶位,需要先分别拿出奇偶位。既然是宏,分别拿出用循环不是很现实,那就用&这些位的方式来做。奇数位拿出,那就是要&上010101010101……,偶数位拿出,就是要&上101010101010……,对应十六进制分别是555……和aaa……,一般我们默认是32位整数,4位对应一位16进制就是8个5,8个a。通过& 0x55555555的方式拿出奇数位和& 0xaaaaaaa的方式拿出偶数位。奇数位左移一位就到了偶数位上,偶数位右移一位就到了奇数位上,最后两个数字或起来,就完成了交换。
※这个宏只能完成32位以内的整形,要想完成64位的,那就将5和a的数量翻倍即可。
例如:
10的二进制:
1010
位数: 4321
解题步骤:
1,奇数位保留,偶数位变为0
0000
2.偶数位保留,奇数位变为0
1010
3.将1得到的0000左移一位
为0000(此时因为奇数被保留,所以我们左移一位那么奇数位就变成偶数位)
4.将2得到的1010右移一位
为0101(此时因为偶数被保留,所以我们左移一位那么偶数位就变成奇数位)
5.相加:
0101
综上:
(1)的奇数位保留,偶数位变为0只需要按位与(&)上01010101010101010101010101010101转成16进制就是:0x55555555
(2)的偶数位保留,奇数位变为0只需要按位与(&)上10101010101010101010101010101010转成16进制就是:0xaaaaaaaa
关于位操作符的介绍:
代码实现:
#define SwapIntBit(n) (((n) & 0x55555555) << 1 | ((n) & 0xaaaaaaaa) >> 1)
#include<stdio.h>
int main() {
int n = SwapIntBit(10);
printf("%d\n", n);
return 0;
}
结果: