参考:
- 博客:https://blog.youkuaiyun.com/Eric_qiushui/article/details/82842890
- 书《C和指针》
问题
编写函数
unsingned int reverse_bits(unsingned int value)
这个函数的返回值是吧 value 的二进制模式从左到右变换一下后的值
例如,在 32 位机器上, 25 这个值包含下列个各位:
00000000 00000000 00000000 00011001
函数的返回值应该是 2 550 136 832 它的二进制模式是:
10011000 00000000 00000000 00000000
main函数
int main()
{
unsigned int num = 25;
printf("num = %u\n",num);
unsigned int result = reverse_bits_bit_oper(num);
printf("res = %u\n",result);
return 0;
}
解法一:旋转字符串
第一步:采用 mod 2 除2 的方式拿到这个数的每一位,并保存到数组中,这样得到了这个数的二进制序列,由于低位存在数组的低索引处,类似于 “小端存储”
第二步:再采用位权的方式把数加起来得到结果
//暴力求解
//采用旋转字符串的方式
unsigned int reverse_bits_bruce(unsigned int value)
{
int array[32]={0};
int i = 0;
unsigned int num = value;
unsigned int result = 0;
//将value的二进制位存进arrray(从低位开始存,就是逆序)
while(num!=0)
{
if(num%2!=0)
array[i]=1;
else
array[i]=0;
num/=2;
++i;
}
// //二进制表示
// int *p;
// for(p=array;p<(array+32);p++)
// {
// printf("%d",*p);
// if((p-array+1)%8==0)//8位输出一个空格
// printf(" ");
// }
// printf("\n");
//二进制转十进制
i=0;
while(i<32)
{
result = result*2+array[i];
i++;
}
return result;
}
解法二:进行位操作
基础知识:
>> 右移 最高位是0,左边补齐0;最高为是1,左边补齐1
<< 左移 左边最高位丢弃,右边补齐0
这里:https://blog.youkuaiyun.com/Eric_qiushui/article/details/82842890 讲的非常好,可以看看
//位操作
unsigned int reverse_bits_bit_oper(unsigned int value)
{
int i = 0;
unsigned int num = value;
unsigned int res = 0;
while(i<32)
{
if(((1<<i)&num)!=0)
res = res | (1<<(31-i));
else
res = res &(~(1<<(31-i)));
++i;
}
return res;
}
//移位操作
unsigned int reverse_bits(unsigned int value)
{
unsigned int answer;
unsigned int i;
answer = 0;
//只要i不是0就继续进行,这就使循环与机器的字长无关,从而避免了可移植性问题
for(i=1;i!=0;i<<=1){
//把旧的answer左移一位,为下一个位置留下空间
//如果value的最后一位是1,answer就与1进行OR操作
//然后将value右移至下一个位
answer <<=1;
if(value&1)
answer|=1;
value>>=1;
}
return answer;
}