正在确定字符中的设置位数

Determining number of set bits in a char

本文关键字:置位 字符      更新时间:2023-10-16

如果每个单元存储为一个设置位,则该程序应确定变量c_val的值中存储了多少个单元。我的问题是:为什么作者写了if (c % 2 == 1) count++;,然后用这个语句c = c >> 1;c向右移动?

#include <stdio.h>
#include <cstdlib>
int main(){
    unsigned char c_val;
    printf("char value = ");
    scanf("%c", &c_val);
    int count = 0;
    unsigned char c = c_val;
    while(c){
        if (c % 2 == 1) count++;
        c = c >> 1;
    }
    printf("%d bits are set", count);
    system("pause");
}

类型char的数据大小总是一个字节-没有例外。然而,此代码计算c_val中的popcount,即1位的数量。

我们可以从翻译相关代码

while (c) {
    if (c % 2 == 1) count++;
    c = c >> 1;
}

while (c != 0) {
    if (c & 0x1 == 1) count++; /* if the rightmost bit of c is 1, then count++ */
    c = c / 2;
}

我所做的最后一个更改之所以有效,是因为对无符号整数数据类型(在本例中为unsigned char)进行右移相当于除以2,语义为向零取整。

我们可以把c看作是比特的传送带——在每次循环迭代中,零个比特从左边进来,一个比特从右边掉下来。如果最右边的位是1,我们将计数增加1,否则计数保持不变。因此,一旦c被零比特填充,我们就知道我们已经计算了所有的一比特,并且正是一比特,所以count包含c_val中的一比特的数量。

这根本不是一个确定char类型实例"大小"的函数,而是一个字符中设置为1的位数。

表达式

c % 2 == 1

确定最低有效位是否是1。

移位将倒数第二个钻头带入最后一个位置,以便对其进行测试。

条件while (c)意味着继续计数1并移位,直到整个字节都为零。

您的代码只是对char c中的1位进行编码。"c%2===1"检查"c"中的最后一位是否为1。因此,我们必须使用"c=c>>1"将"c"中的其他位移到最后一个位置。

其他相同的方法:

#include <stdio.h>
#include <conio.h>
unsigned int f (unsigned int a , unsigned int b);
unsigned int f (unsigned int a , unsigned int b)
{
   return a ?   f ( (a&b) << 1, a ^b) : b;
}
int bitcount(int n) {
    int tot = 0;
    int i;
    for (i = 1; i <= n; i = i<<1)
        if (n & i)
            ++tot;
    return tot;
}
int bitcount_sparse_ones(int n) {
    int tot = 0;
    while (n) {
        ++tot;
        n &= n - 1;
    }
    return tot;
}
int main()
{
int a = 12;
int b = 18;
int c = f(a,b);
printf("Sum = %dn", c);
int  CountA = bitcount(a);
int  CountB = bitcount(b);
int CntA = bitcount_sparse_ones(a);
int CntB = bitcount_sparse_ones(b);
printf("CountA = %d and CountB = %dn", CountA, CountB);
printf("CntA = %d and CntB = %dn", CntA, CntB);
getch();
return 0;
}