确定在字节单位被设置 [英] Determine which single bit in the byte is set
问题描述
我有我使用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 thebyte
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
uint16
s, four foruint32
s...). 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屋!