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

本文探讨了两种实现 unsigned int 类型的二进制反转函数的方法,第一个使用了错误的逻辑导致效率低下,第二个通过移位和位操作优化,解决了1和2147483648反转问题。作者逐步剖析了问题所在并给出了修正后的高效代码。

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

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

value是我们想要求的值。

#include

#include

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则只进行幂数减减。

718d2a25d34bea81d0312a72e47e8a40.png

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

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

#include

#include

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;

}

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

99ab85bce9d4a74d24230ffc9ac20567.png

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

int main ()

{

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

return 0;

}

让我们看看结果:

ec4d5a11f5f589d007b26d9e19e5384f.png

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

那我们再把主函数改成:

int main ()

{

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

return 0;

}

我们再来看看结果:

3b10c6d02becb9f37bc86472b96b48d8.png

此时运行结果为什么不是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));

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

fdfa1e5965123366d2d564fda40b0930.png

结果对了!那么程序就对了!

那么我们试着把主函数改为:

int main ()

{

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

return 0;

}

我们再来验证一下结果

ec4d5a11f5f589d007b26d9e19e5384f.png

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

我们看看正确的程序:

#include

#include

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、付费专栏及课程。

余额充值