【Leetcode】一个无符号的整数,如何翻转其二进制位?

方法一:可以采用下面的方法,以32位整数为例:

unsigned int v; // 32-bit word to reverse bit order

// 相邻两位互相交换
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);

// 相邻的一对互相交换
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);

// 相邻的一组(4位)互相交换
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);

// 相邻的一组(8位)互相交换
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);

// 相邻的一组(16位)互相交换
v = ( v >> 16) | ( v << 16);
// 第1步:对调相邻的1位(abcd efgh-> badc fehg)
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555)<< 1);
// 第2步:对调相邻的2位(abcd efgh-> cdab ghef)
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// 第3步:对调相邻的4位(abcd efgh-> efgh abcd)
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// 第4步:对调相邻的8位(相邻的字节)
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// 第5步:对调相邻的16位(相邻的两字节)
v = ( v >> 16             ) | ( v               << 16);

经过上面的步骤,一个32位整数的二进制位已经翻转了。上面的对调步骤是互不干扰的,因此顺序可以倒过来,也就是先对调相邻16位,然后是8位、4位、2位和1位。

也可以使用下面这个方法:

//也可以使用循环
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
	unsigned int a;
	scanf("%d", &a);
	unsigned int reversed_a = 0;
	for(int i = 0; i < 32; i++)
	{
		/* 左移腾出空位 */
		reversed_a = reversed_a << 1;
		/* 与上最后一位 */
		reversed_a |= (a & 0x1);
		/* 右移,将要移位的放到最后一位上 */
		a = a >> 1;
	}
	printf("%u", reversed_a);

	system("pause");
	return 0;
}
posted @ 2024-09-09 22:29  Tyler77  阅读(124)  评论(0)    收藏  举报