由二进制翻转问题引发的思考
2016-04-03 16:58
211 查看
今天在做一道关于将一个数的二进制模式从左到右翻转时引发了一些思考,于是就赶紧记录下来,方便日后查看。原题是编写一个函数:这个函数返回一个输入值value的二进制位模式从左到右翻转后的值。题目本身并不难,但是即使是再小的题目也有它存在的意义。每道题目都能教会我们一些知识。
首先是方法:最容易想到也是一般最先想到的是定义一个arr[32]的数组。将输入值value每次对2取余,然后将余数依次从数组的第一位开始存放,接着将每一位乘上位权后相加,最后返回结果。当然转念一想其实根本用不到数组,只要将余数乘上它移位之后的位权即可,然后相加。当然方法是无穷无尽的。
我的想法是首先定义一个存放最后的值的变量sum并初始化为0,value&1(取它最后一位的数字),然后sum或等上(value&1),接着value的值每次右移一位,当然sum也要每次左移一位,但是写在什么位置合适呢?开始我习惯性的写在后面,但是程序出现了问题。结果是错误的。
现附上我最初写的:
程序看上去没什么问题,但是结果却是错的,后来看了半天,发现把一个32位的二进制数字拿下来只需要31次移动就可以了,而上面的程序循环换了32次,所以所得到的结果会比原来多1倍。答案也就错了,很容易就会想到是不是把循环次数32改成31就行了呢?
改成31之后:
改了之后试了几个数字确实答案是正确的。但是整个程序却出现了逻辑问题,首先就是最高位也就是第32位的值永远也拿不到了,程序也就是错误的程序。因此必须要让它浪费一次位移的次数。所以将程序稍加修改即可:让它先执行右移,再去执行其他的步骤。
这样程序才是对的,哪怕数字变大了,答案也是对的。
首先是方法:最容易想到也是一般最先想到的是定义一个arr[32]的数组。将输入值value每次对2取余,然后将余数依次从数组的第一位开始存放,接着将每一位乘上位权后相加,最后返回结果。当然转念一想其实根本用不到数组,只要将余数乘上它移位之后的位权即可,然后相加。当然方法是无穷无尽的。
我的想法是首先定义一个存放最后的值的变量sum并初始化为0,value&1(取它最后一位的数字),然后sum或等上(value&1),接着value的值每次右移一位,当然sum也要每次左移一位,但是写在什么位置合适呢?开始我习惯性的写在后面,但是程序出现了问题。结果是错误的。
现附上我最初写的:
<span style="font-size:18px;">#include<stdio.h> #include<math.h> unsigned int reverse_bit(unsigned int value) { int i; unsigned int sum = 0; unsigned int num = value; for ( i = 0; i < 32; i++) { sum |= (num&1); sum <<= 1; num >>= 1; } return sum; } int main() { unsigned int number = 0; unsigned int ret = 0; printf("请输入一个数字\n"); scanf("%d",&number); ret = reverse_bit(number); printf("翻转后的值为:%u",ret); return 0; }</span>
程序看上去没什么问题,但是结果却是错的,后来看了半天,发现把一个32位的二进制数字拿下来只需要31次移动就可以了,而上面的程序循环换了32次,所以所得到的结果会比原来多1倍。答案也就错了,很容易就会想到是不是把循环次数32改成31就行了呢?
改成31之后:
改了之后试了几个数字确实答案是正确的。但是整个程序却出现了逻辑问题,首先就是最高位也就是第32位的值永远也拿不到了,程序也就是错误的程序。因此必须要让它浪费一次位移的次数。所以将程序稍加修改即可:让它先执行右移,再去执行其他的步骤。
<span style="font-size:18px;">#include<stdio.h> #include<math.h> unsigned int reverse_bit(unsigned int value) { int i; unsigned int sum = 0; unsigned int num = value; for ( i = 0; i < 32; i++) { sum <<= 1; sum |= (num&1); num >>= 1; } return sum; } int main() { unsigned int number = 0; unsigned int ret = 0; printf("请输入一个数字\n"); scanf("%d",&number); ret = reverse_bit(number); printf("翻转后的值为:%u",ret); return 0; }</span>
这样程序才是对的,哪怕数字变大了,答案也是对的。
相关文章推荐
- mysql安装以及启动小问题总结
- [090626]痕 ~きずあと~【日文硬盘版】[痕+雫&Origin][全CG存档&攻略=日本语启动+打开存档补丁]
- 全系统动态污点分析-概要
- LeetCode之旅(17)-Ugly Number
- 【MFC】:MFC如何给控件设计缺省值?
- Android SDK manager 设置
- 插入排序法(二)
- ip段/数字,如192.168.0.1/24是什么意思?
- LeetCode之旅(17)-Ugly Number
- LeetCode之旅(17)-Ugly Number
- PeopleSoft介绍
- 顺序表 线性表 数组的区别
- 四则运算完结篇
- 最小费用流
- 如何排版文字较多的PPT?
- 自己写的后台管理系统
- spark rdd存储开销分析
- 【Android】如何实现一个简单的文件浏览器
- Oracle dataguard之主备库切换(switchover)
- 【JavaScript】出现即使设置了ID也获取不到的可能原因与window.onload