C语言交换二进制位的奇数偶数位

时间:2024-04-04 16:14:31

基本思路

我们要先把想要交换的数的二进制位给写出来假如交换13的二进制位,13的二进制位是

0000 0000 0000 0000 0000 0000 0000 1101

然后写出偶数位的二进制数(偶数位是1的)

1010 1010 1010 1010 1010 1010 1010 1010

然后写出奇数位的二进制数(奇数位是1的)

0101 0101 0101 0101 0101 0101 0101 0101

最后把奇数位的二进制数,和偶数位的二进制数都和原来的数进行按位与然后奇数位向>>1向右移动1位就挪到了偶数位,偶数位向<<1向左移一位就挪到了奇数位,最后两个移动完的二进制位按位或就得到了奇数偶数位互换,像这张图
在这里插入图片描述

下面是代码

# include<stdio.h>
int main()
{
	int num = 13;
	printf("交换前\n");
	for (int i = 0; i < 32; i++)
	{
		if (((num >> i) & 1) == 1)
		{
			printf("%d", 1);
		}
		else
		{
			printf("%d", 0);
		}
	}
	printf("\n");
	int temp = (num & 0x5555555555555555) << 1;
	int temp2 = (num & 0xAAAAAAAA) >> 1;
	int swap = temp | temp2;
	int a = 0;
	printf("交换后\n");
	for (int i = 0; i < 32; i++)
	{
		if (((swap >> i) & 1) == 1)
		{
			printf("%d", 1);
		}
		else
		{
			printf("%d", 0);
		}
	}
	return 0;
}

为什么打印出来是反的,那是由于在VS2022下是小端字节序存储是倒着存放的

0x5555555555555555就是奇数位
0xAAAAAAAA就是偶数位

define宏实现

同样用define宏定义也可以完成奇数偶数互换,下面是代码

# include<stdio.h>
# define SWAP(num) (num) = ((((num)&0xAAAAAAAA)>>1) | (((num)&0x5555555555555555)<<1))
int main()
{
	int num = 13;
	SWAP(num);
	printf("%d", num);
	return 0;
}

为什么define宏要打那么多括号呢,那是由于我们必须要确定好运算顺序和优先级,打括号保险一点,可以避免不可预料的后果