【C语言】求一个数的二进制位模式从左到右翻转后对应的十进制值。

来源:互联网 发布:淘宝助理修改宝贝描述 编辑:程序博客网 时间:2024/05/16 15:24

用函数unsigned int reverse_bit(unsigned int value)实现想要的功能

value是我们想要求的值。

#include <stdio.h>#include <math.h>unsigned int reverse_bit(unsigned int value){    int sum= 0;    int n = 31;    for(;value != 0,n != 0; value = value >> 1,n--)     {             if(value & 1)            {                sum += 1*pow(2,n);            }    }    return sum;}int main (){    printf("%u\n",reverse_bit(25));     return 0;}

本题用到数学库的函数pow,其作用是计算幂,比如pow(2,n)是计算2的n次幂。
大致思路是:一个数–>00000000 00000000 00000000 00011001
当最后一位是1时,我们都将它乘以2的31次方,接着将31减1(幂数减减),并累计每次乘积和;若最后一位是0则只进行幂数减减。

但是如果最后一位是1,那么每次都需要进行累加和计算,所以,这样的程序,效率往往还是很差的。上面的程序感觉没有错误,但是当你输入1时,看看运行结果是不是你想要得到的。所以上面的程序是错误的。

针对上面程序,下面提供了另一种解决方案:

#include <stdio.h>#include <math.h>unsigned int reverse_bit(unsigned int value){    int ret = 0;    int one = 0;    int i = 0;    for(i=0; i<32; i++)    {        one = value & 1;        ret = ret | one;        ret <<= 1;        value = value >> 1;    }    return ret;}int main (){    printf("%u\n",reverse_bit(25));     return 0;}

这个程序主要采用了移位运算符,我们来验证一下结果:

当我们看到运行结果中的25对应二进制翻转后的十进制数并不符合我们的要求时,肯定知道程序写错了,但是你知道错在哪里吗?我们不妨把实参改为1,即把主函数改为:

int main (){    printf("%u\n",reverse_bit(1));     return 0;}

让我们看看结果:

此时你发现如果把1移到最高位,输出的应该是2147483648,但是为什么却是0呢?

那我们再把主函数改成:

int main (){    printf("%u\n",reverse_bit(2147483648));     return 0;}

我们再来看看结果:

此时运行结果为什么不是1而是2呢?我们发现在32位系统下,本来我们只需要移动31次就能达到把最低位移到最高位上,而程序的for循环中也正是移动31次。当进入执行for循环时,ret是在执行完一次操作后才开始左移,所以无形当中已经增加了一次左移操作。那好,既然运行结果不正确,是因为ret多移动了一位,那么我们就试着把for循环中的32改成31,也就是:

for(i=0; i<31; i++)    {        one = value & 1;        ret = ret | one;        ret <<= 1;        value = value >> 1;    }

主函数中的输出我们依然用:

printf("%u\n",reverse_bit(1));

紧接着我们验证一下结果:

结果对了!那么程序就对了!
那么我们试着把主函数改为:

int main (){    printf("%u\n",reverse_bit(2147483648));     return 0;}

我们再来验证一下结果

为什么结果依然不是1呢?我们换个角度思考,既然ret是在第一次操作后多移动了一次,那么我们可不可以在ret执行第一次操作之前先移动一位,而ret初始化为0,所以既然一共要移动31位,又不影响运行结果,那么我们可以改变一下for循环中语句的执行顺序

我们看看正确的程序:

#include <stdio.h>#include <math.h>unsigned int reverse_bit(unsigned int value){    int ret = 0;    int one = 0;    int i = 0;    for(i=0; i<32; i++)    {        ret <<= 1;        one = value & 1;        ret = ret | one;        value = value >> 1;    }    return ret;}int main (){    printf("%u\n",reverse_bit(1));     return 0;}

此时再去验证运行结果是否正确的工作就留给你们啦~~~~

1 0
原创粉丝点击