cbitwise-operatorstdm-mingw

Counting bits in a long long not working as expected


uint64_t bitsToInt64(char *bs) {
    uint64_t r, i;
    r = 0;
    for(i = 0; i < 64; i++)
        if(bs[i] == 1) 
            r |= 1LL << i;          
    return r;
}

int countBits64(uint64_t i) {
    uint64_t x, t;
    t = 0LL;
    for(x = 0LL; x < 64LL; x++) {
        if(i & (1LL << x))
            t += 1;
    }
    return t;
}

char bits [] = { 
    0, 0, 0, 0, 1, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 1, 1, 1, 1, 1, 1,};

uint64_t mask = bitsToInt64(bits);
int nbits = countBits64(mask);
printf("%d", nbits);

The above is printing "1". What am I doing wrong?


Solution

  • With the code below I was able to get the following output

    (0xFF00000000000010) 9

    Make sure you use the correct size values. The literal constants need ULL so that they match uint64_t and the for loop variables only need to be an int, as well as the return value for countBits64.

    uint64_t bitsToInt64(char *bs) {
        uint64_t r;
        int i;
        r = 0;
        for(i = 0; i < 64; i++)
            if(bs[i] == 1) 
                r |= 1ULL << i;          
        return r;
    }
    
    int countBits64(uint64_t i) {
        int x, t = 0;
        for(x = 0; x < 64; x++) {
            if(i & (1ULL << x))
                t += 1;
        }
        return t;
    }
    
    char bits [] = { 
        0, 0, 0, 0, 1, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        1, 1, 1, 1, 1, 1, 1, 1,};
    
    uint64_t mask = bitsToInt64(bits);
    int nbits = countBits64(mask);
    printf("(0x%016llX) %d",mask, nbits);