目录
题目
实例
方法一:直接交换
方法二:间接交换
拓展
题目
编写一个函数,将一个无符号整数的所有位逆序(在32位机器下)
实例
例如有一个无符号整数
unsigned int num = 32;
unsigned int 在32位系统中占4个字节(32位)
32的二进制数是: 0000 0000 0000 0000 0000 0000 0010 0000
逆序后的二进制数是: 0000 0100 0000 0000 0000 0000 0000 0000
逆序后10进制数是 : 1 * 2^26 = 67108864
方法一:直接交换
思路:就是将num的最高位和最低位依次取出并交换
问题来了: 如何依次取出最高位和最低位呢?
先说最低位:
可以利用 0 & 1 = 0 , 1 & 1 = 1的方法判断,即可用0x00000001和num进行&运算,如果结果是0则表示最低位是0,否是是1
同理:最高位将num与0x80000000进行&运算(因为8的二进制是10000),如果结果是0则表示最低位是0,否是是1
取出最高位最低位就可以进行交换。
if(最高位是1)
{
将最低位变成1
利用 0 | 1 = 1 , 1 | 1 = 1来进行操作
num = num | 0x00000001;// 即最低位变成1
}
else
{
将最低位变成0
利用 0 & 1 = 1 , 1 & 1 = 1来进行操作
num = num & 0xFFFFFFFE;// 即最低位变成0
0xFFFFFFFE还可以换一种写法: ~(0x00000001) 这样方便移位
}
最低位同理
unsigned int reverseBits(unsigned int num)
{
int i;
for (i = 0; i < 16; i++)
{
// 左往右依次取出num最高位
unsigned int hight = (num & 0x80000000 >> i) == 0 ? 0 : 1;
// 右往左依次取出num最低位
unsigned int low = (num & 0x00000001 << i) == 0 ? 0 : 1;
// 改变最低位
if (hight == 1)
{
// 低位变成1
num |= (0x00000001 << i);
}
else
{
// 低位变成0
num &= ~(0x00000001 << i);
}
// 改变最高位
if (low == 1)
{
// 高位变成1
num |= (0x80000000 >> i);
}
else
{
// 高位变成0
num &= ~(0x80000000 << i);
}
}
return num;
}
方法二:间接交换
思路:就是将num的各个位取出并逆序存放在数组中,然后转成十进制
// 思路就是将各个位都取出来 逆序存在数组
unsigned int reverseBits_2(unsigned int num)
{
int bits[32]; // 存放num的各个位
int i;
for (i = 0; i < 32; i++)
{
if (((num >> i) & 1) == 1)// 判断num的最低位是0还是1
{
bits[32 - i - 1] = 1;
}
else
{
bits[32 - i - 1] = 0;
}
}
// 再组合(就是已知二进制数求10进制数)
unsigned int ret = 0;
for (i = 0; i < 32; i++)
{
if (bits[i] != 0)
{
ret += (unsigned int)pow(2, i);
}
}
return ret;
}
拓展
求一个数二进制1的个数
//方法一:1 左移
for (int i = 0; i < 32; i++) {
if((num&(1<<i)) == (1<<i)){
count++;
}
}
//方法二:数字右移
for (int i = 0; i < 32; i++){
if(((num>>i)&1)==1){
count++;
}
}
//方法三:减一&本身减一相当于将最后一个 1 消掉,后面的0变为1,在&相当于去掉 最后一个1
while (num!=0){
num=(num-1) & num;
count++;
}