How do I count the number of zero bits in an integer?

前端 未结 12 2112
梦谈多话
梦谈多话 2021-02-02 00:25

How would i go about finding the number of \'zero\' bits in C++. Suppose I have an integer;

int value = 276; 

For which I have the bits 100010

12条回答
  •  北恋
    北恋 (楼主)
    2021-02-02 00:42

    Expanding on ronag's answer, which other users have mentioned leads to wrong results (his algorithm works only up to a value of x = 15), here is an updated version of the algorithm:

    uint8_t count_1bits(uint32_t x) {
        x = x - ((x >> 1) & 0x55555555);
        x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
        x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
        x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
        x = (x & 0x0000FFFF) + ((x >> 16) & 0x0000FFFF);
        return x & 0x3F;
    }
    
    uint8_t count_0bits(uint32_t x)    {
        return 32 - count_1bits(x);
    }
    

    The explanation of the first line from ronag is correct, however, the remaining lines are using a different approach. In the first line, through the shifting and subtracting, each 2-bit pair will contain the number of bits that were set in that pair in the original number. The rest of the lines recursively fold those numbers together by adding the lsb of each 2n-bit group to the msb of that pair shifted by n, so that the 2n-bit group contains the number of bits that was set in that group in the original number:

    01110110: 0111 (7 bits were set in the original number) 0110 (6 bits were set in the original number)
    -> 01110110 & 00001111 + (01110110 >> 4) & 00001111
    = 0110 + 0111
    = 1101
    

    The above algorithm works for 32 bit integers, but can easily be adapted by changing the constants to the correct bit-length so that the pattern stays the same (e.g. 0x5555... = 0101..., 0x0f0f... = 00001111... etc.) and adding/removing the appropriate shifts

提交回复
热议问题