将一个数进行反写的方法
这里举一个具体例子来帮助理解一下:
num=1012;
进入循环:
① t=0*10+num%10=2
num=num/10=101
② t=2*10+num%10=21
num=num/10=10
③ t=21*10+num%10=210
num=num/10=1
④ t=210*10+num%1=2101
num=num/10=0
每次从末尾取出一个数放到最前面(我们假设末尾的数是t),与此同时,将原来的数字(这里即上面的num)的最后一位舍弃掉。每经历过一次这样的过程,那么t就往前前进一位,而此时又有一个新的数被放到末尾。直到最后num=0循环终止。
对计算机储存数据(补码)的操作、
eg:
统计二进制中1的个数
写一个函数返回参数二进制中 1 的个数。
比如: 13 0000 1101 3 个 1
我们可以参考上面的代码:
对于一个十进制数n1来说 通过n1%10 n1/10这两个操作可以把n1的末尾数拿出来并舍弃
那么,对于一个二进制数n2来说 通过n%2 n2/2这两个操作可以把n2的末尾数拿出来并舍弃
于是有:
缺陷:需要注意的是,在数据在计算机中储存的时候是以二进制形式储存的(整型以补码的形式储存),而进行运算的时候是以本身的数字进行运算。比如说4/2=2,是4和2参与运算,不是00000000000000000000000000000100(4的二进制)和00000000000000000000000000000010(2的二进制)进行运算。因此上述代码在处理负数的时候(eg:-1),(-1)%2=0,(-1)/2=0,会出现打印结果为0的情况
但是如果用unsigned int 类型的话,就将-1的补码转换为2^32(4294967296)就适用上述类型了
按位与和右移运算符解决:
这里先普及一下按位与和右移运算符
左右移运算符:
注意:这里移动的是二进制位
按位与运算符:
于是有
可以发现这需要统计32次。
补码中中舍弃最后一个1的方法:
这里以13为例:
13的二进制表示:
00000000000000000000000000001101——原码
011111111111111111111111111111110010——反码
011111111111111111111111111111110011——补码
step1:
step2:
step...
可以发现,每进行一次运算,原数的最后一个1就变成0,最后整个数变为0,我们只需统计进行了多少次运算就可以。
于是:
这个算法不需要统计32次,有多少个1就统计多少次。