Determine which single bit in the byte is set

后端 未结 8 984
臣服心动
臣服心动 2020-12-03 18:53

I have a byte I\'m using for bitflags. I know that one and only one bit in the byte is set at any give time.

Ex:

8条回答
  •  情话喂你
    2020-12-03 19:34

    Can I do this without iteration?

    It is indeed possible.

    How do I most efficiently determine the position of the set bit?

    You can try this algorithm. It splits the char in half to search for the top bit, shifting to the low half each time:

    int getTopSetBit(unsigned char b) {
      int res = 0;
      if(b>15){
        b = b >> 4;
        res = res + 4;
      }
      if(b>3){
        b = b >> 2;
        res = res + 2;
      }
    
      //thanks @JasonD
      return res + (b>>1);
    }
    

    It uses two comparisons (three for uint16s, four for uint32s...). and it might be faster than your loop. It is definitely not shorter.


    Based on the idea by Anton Kovalenko (hashed lookup) and the comment by 6502 (division is slow), I also suggest this implementation (8-bit => 3-bit hash using a de-Bruijn sequence)

    int[] lookup = {7, 0, 5, 1, 6, 4, 3, 2};
    
    int getBitPosition(unsigned char b) {
      // return lookup[(b | (b>>1) | (b>>2) | (b>>4)) & 0x7];
      return lookup[((b * 0x1D) >> 4) & 0x7];
    }
    

    or (larger LUT, but uses just three terms instead of four)

    int[] lookup = {0xFF, 0, 1, 4, 2, 0xFF, 5, 0xFF, 7, 3, 0xFF, 0xFF, 6, 0xFF, 0xFF, 0xFF};
    
    int getBitPosition(unsigned char b) {
      return lookup[(b | (b>>3) | (b>>4)) & 0xF];
    }
    

提交回复
热议问题