确定在字节单位被设置 [英] Determine which single bit in the byte is set

查看:175
本文介绍了确定在字节单位被设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我使用bitflags一个字节。我知道, 且只有一个的<强/>在字节位设置在任何给的时间。

例如: unsigned char型B = 0x20的; //(00100000),6日最高位集

我目前使用下面的循环,以确定哪些位设置:

  INT getSetBitLocation(unsigned char型B){
  INT I = 0;
  而(((B&GT;!I标记++)及0×01)){; }
  返回我;
}

我如何最有效地确定设置位的位置?我能做到这一点不重复?


解决方案

  

我能做到不重复?


这的确是可能的。


  

我如何最有效地确定设置位的位置?


您可以试试这个算法。它分割焦炭在一半要搜索的顶部位,每次移位到低半

  INT getTopSetBit(unsigned char型B){
  INT RES = 0;
  如果(B→15){
    B = B个;&GT; 4;
    RES = RES + 4;
  }
  如果(B→3){
    B = B个;&GT; 2;
    RES = RES + 2;
  }  //感谢@JasonD
  返回RES +(B&GT;&GT; 1);
}

它使用两个比较(三为 UINT16 S,四为 UINT32 取值...)。它可能比你的循环速度更快。这绝对不是短。


使用的由6502上安东科瓦连科(散列查找)和注释的想法基于(分割是慢),我也建议该实现(8位=> 3比特的散列=HTTP:/ /en.wikipedia.org/wiki/De_Bruijn_sequence相对=nofollow>去Bruijn的序列)

  INT [] =查找{7,0,5,1,6,4,3,2};INT getBitPosition(unsigned char型B){
  //返回查找[(二|(B个→1)|(B个→2)|(B个→4))及为0x7]
  返回的查找[((b *的0x1D)GT;→4)及为0x7]
}

或(LUT较大,但仅使用三个术语而不是四个)

  INT []查找= {0xFF的,0,1,4,2,为0xFF,5,为0xFF,7,3,为0xFF,0xFF的,6,为0xFF,0xFF的,0xFF的} ;INT getBitPosition(unsigned char型B){
  返回的查找[(二|(B个→3)|(B个→4))及0xF的];
}

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: unsigned char b = 0x20; //(00100000) 6th most bit set

I currently use the following loop to determine which bit is set:

int getSetBitLocation(unsigned char b) {
  int i=0;
  while( !((b >> i++) & 0x01) ) { ; }
  return i;
}

How do I most efficiently determine the position of the set bit? Can I do this without iteration?

解决方案

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];
}

这篇关于确定在字节单位被设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆