一个16位二进制数中1的个数可以通过位运算高效计算。以下是两种常用方法:
方法一:逐位检查法
通过循环右移和按位与操作,逐位检查最低位是否为1,并统计1的个数。
```c
include
int countones(unsigned short x) {
int count = 0;
while (x) {
count += (x & 1); // 检查最低位是否为1
x >>= 1; // 右移一位
}
return count;
}
int main() {
unsigned short num = 0xFFFF; // 示例数
printf("0x%04X: %dn", num, countones(num)); // 输出: 0xFFFF: 16
return 0;
}
```
方法二:Brian Kernighan算法
通过不断将数减1并与原数进行按位与操作,每次操作都会将最右边的1变为0,从而快速统计1的个数。
```c
include
int countones(unsigned short x) {
int count = 0;
while (x) {
x &= (x - 1); // 将最右边的1变为0
count++; // 统计1的个数
}
return count;
}
int main() {
unsigned short num = 0x0002; // 示例数
printf("0x%04X: %dn", num, countones(num)); // 输出: 0x0002: 1
return 0;
}
```
说明
数据类型选择 :使用`unsigned short`确保处理16位无符号数,范围为0到65535。
算法复杂度
- 逐位检查法:O(k),其中k是1的个数。
- Brian Kernighan算法:O(k),但实际运行效率更高,因为每次操作减少一个1。
示例
- `0xFFFF`(二进制16个1):`countOnes(0xFFFF)`返回16。
- `0x0002`(二进制2个1):`countOnes(0x0002)`返回1。
这两种方法均可正确统计16位二进制数中1的个数,选择时可根据具体需求(如性能要求)决定。