前言
本篇博客介绍C语言中一个整数如何计算其二进制中所含1的个数。
一、运用取余与除法运算的方法
1.1 一般算法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int count_bit_one(int n) {
int count = 0;
while (n) {
if (n % 2 == 1) {
count++;
}
n = n / 2;
}
return count;
}
int main()
{
int a = 0;
scanf("%d", &a);
int count = count_bit_one(a);
printf("count = %d\n", count);
system("pause");
return 0;
}
上述代码中,若输入为5,则为00000000 00000000 00000000 00000101,在函数count_bit_one中,首先判定n取模是否余1,若余1,则将count加1,即将二进制中最后一字节00000101中最后一个1余掉,再将n除以2取整。
但在该代码中,不能计算整数为负数,假如为-1,取模为-1,故count不能加1,且-1整除2余0,故退出,count为0。但-1在计算机中储存的补码为11111111 11111111 11111111 11111111,故有32个1,故需对代码进行改良。
1.2 改良算法
int count_bit_one(unsigned int n) {
int count = 0;
while (n) {
if (n % 2 == 1) {
count++;
}
n = n / 2;
}
return count;
}
在此代码中,将整数n强制转化为无符号位的int,则会将负数的符号位作为正常的有效位带入计算,则可正常计算。正数的原码、反码、补码相同,则不影响其正常运算。
二、利用按位与和移位进行运算
若计算形如00000000 00000000 00000000 00000101,则将其按位与1,其二进制为00000000 00000000 00000000 00000001,若相与结果为1,则证明其最后一位为1,若相与结果为0,则证明其最后一位为0。然后向右依次移位,再进行上述计算,得到最后1的个数。
int count_bit_one(unsigned int n) {
int count = 0;
for (int i = 0; i < 32; i++) {
if(((n>>i)&1)==1){
count++;
}
}
return count;
}
三、n与n-1相与消除最右侧1
假设一个数字11,二进制数为00000000 00000000 00000000 00001011,n-1即为10,其二进制数为00000000 00000000 00000000 00001010,若两者相与,则二进制为00000000 00000000 00000000 00001010,则会将最右侧的1进行消除,在进行如上重复操作,则会依次消除,由此设计代码。
int count_bit_one(int n) {
int count = 0;
while (n) {
n = n & (n - 1);
count++;
}
return count;
}
由此代码,即当n相与不等于0时,将count加1并进行输出用以计算。
总结
利用三种方法对该题目进行计算,用以拓宽思路,对解决思想进行补充。
若需要计算二进制中0的个数,则按位取反,进行上述1的个数求解,最后相减则可计算得出。