1.通过取余、取模计算
2.通过左、右移操作符与位操作符计算
法一:
如果n=1234
则1234%10=4,1234/10=123;123%10=3,123/10=12;12%10=2,12/10=1;1%10=1,1/10=0.
得到十进制数字1234各个位上的数字。
同理,计算n的二进制序列“1”的个数就用n%2,n/2;(n/2)%2,(n/2)/2…最后数出n%2、(n/2)%2、((n/2)/2)%2…中等于“1”的有多少。
代码展示:
#include <stdio.h>
int main()
{
int n = 0;
scanf_s("%d", &n);
int count = 0;//计算n的二进制序列“1”的个数
while (n)//若n多次除以2的结果位0,则循环结束
{
if (n % 2 == 1)//先从二进制序列的右边检查
{
count++;
}
n = n / 2;//再将检查过了的位去掉,往左继续检查下一位
}
printf("有%d个\n", count);//输出个数
}
法二:
计算15的二进制序列中有多少个“1”,(8位的形式储存)
15的二进制序列为00001111,1的二进制序列为00000001
不妨将15&1=00000001
再将15>>1,继续上述操作,即有(15>>1)&1=00000001;((15>>1)>>1)&1=00000001;(((15>>1)>>1)>>1)&1=00000001…
上述操作一共要进行8次,也就是全部位都要检查,故经检查,15的二进制序列共有4个“1”。
代码展示:
#include <stdio.h>
int main()
{
int n = 0;
scanf_s("%d", &n);
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)//此处i<32是由于该程序中处理的n的二进制是以32位的形式储存的
{
if ((n >> i) & 1)//从n的二进制序列的右向左依次与1做按位与运算
{
count++;//记录“1”出现的次数
}
}
printf("%d", count);//输出个数
}
法三:
例:计算15的二进制序列中有多少个“1”,(8位的形式储存)
15二进制为00001111,15<<1=00011110,所以15&(15<<1)=00001110;
同理,(15&(15<<1))&((15&(15<<1))<<1)=00001100…共进行了四次这样的运算,故有4个“1”
观察到,每进行一次按位与运算原二进制序列中“1”的个数就少一个,当数量减为0时记录运算次数。
代码展示:
#include <stdio.h>
int main()
{
int n=0;
scanf_s("%d", &n);
int count = 0;
while (n)
{
if (n & (n << 1))//逐个减少n的二进制序列中“1”的个数
{
count++;
}
n = n & (n << 1);
}
printf("%d", count);//输出个数
}