确定char中的设置位数

时间:2012-03-26 05:45:21

标签: c++ c

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

#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");
}

4 个答案:

答案 0 :(得分:6)

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中的一位数。

答案 1 :(得分:3)

这不是确定char类型实例的“大小”的函数,而是确定字符中设置为1的位数。

表达式

c % 2 == 1

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

移位使倒数第二位进入最后位置,以便进行测试。

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

答案 2 :(得分:2)

您的代码只是编码char c中的多少1位。 “c%2 === 1”检查“c”中的最后一位是否为1.所以我们必须使用“c = c&gt;&gt; 1”将“c”中的其他位移到最后一位。 / p>

答案 3 :(得分:0)

  

其他方式:

#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 = %d\n", 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 = %d\n", CountA, CountB);
printf("CntA = %d and CntB = %d\n", CntA, CntB);
getch();

return 0;

}