checking the number of bits ON in a byte?

走远了吗. 提交于 2019-12-13 05:16:53

问题


I know we can set any bit in the byte by using logical OR and can clear any bit by logical AND like to

    val |= (1<<order_number_of_bit_to_set);   //for setting some specific number of bit 

and for clearing a bit

    val &= ~(1<<order_number_of_bit_to_clear); // specific bit to clear

but my question is how can we check that how many and which ordered number bits are set in the byte.

for example if we have

    val = 0x22;

it means that 2nd and 5th bit is set in the byte

what is the efficient, quick and shortest way to do this?

The quick solution that came to mind is to iterate through all bits and check their order and if it is set record and display the order of the bit.

But is there any other efficient way to do this?


回答1:


You should check this Built-Ins declarations you can use the function __builtin_popcount (unsigned int x) Returns the number of 1-bits in x.




回答2:


Modified From @0x499602D2's answer above:

int pos[sizeof(/* decltype(val) */)];
int bits_on = 0;
for (int i = sizeof(/* decltype(val) */) * CHAR_BIT - 1; --i;)
{
    pos[i] = (val >> i) & 1;
    if(pos[i]) bits_on++;
}  

Gives total and position.




回答3:


The count of on bits may be optimized a bit.

int bits_on(int x)
{
   x = (x & 0x55555555) + ((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;
}

But the positions have to be found by a loop. (it is in other's answers.)




回答4:


Here's a combination of two algorithms, which iterates as many times as there are set bits:

unsigned count_low_zerobits(unsigned n) {
    static const unsigned MultiplyDeBruijnBitPosition[32] =
    {
        0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
        31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
    };
    return MultiplyDeBruijnBitPosition[((n & -n) * 0x077CB531U) >> 27];
}

unsigned find_bits(unsigned n, unsigned positions[]) {
    unsigned c;
    for (c = 0; n; c++) {
        unsigned bitnum = count_low_zerobits(n); // get bit number of lowest bit
        positions[c] = bitnum; // put number to positions array
        n ^= 1 << bitnum; // use XOR to unset just this one bit
    }
    return c;
}

Reference for more info about count_low_zerobits: an answer of question Position of least significant bit that is set .

Function find_bits then simply calls this, puts given bit position to result array, and uses it to unset this bit using bitwise exclusive-or.

Finally, for convenience, a piece of ugly code I used to test this:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    unsigned positions[128] = {0};
    int testnumber = 4442344;

    unsigned count = find_bits(testnumber, positions);

    // non-standard, leaking one-liner for debug purposes, remove if fails to compile:
    printf ("Number in binary: %s\n", itoa(testnumber, malloc(129), 2));

    printf("%u bits: ", count);
    for(unsigned i = 0 ; i < count ; ++i) {
        printf("%u ", positions[i]);
    }
    printf("\n");

    return 0;
}


来源:https://stackoverflow.com/questions/19106342/checking-the-number-of-bits-on-in-a-byte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!