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

本文介绍了使用位操作实现数值位反转的优化方法,并通过实例分析了两种不同算法的效率和适用场景。重点讨论了如何避免冗余操作,提高算法性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用函数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;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值