当你不知道哪个最左边的' 1'有点?

时间:2014-09-05 15:30:24

标签: bitmap bit-manipulation

0000 => 0000
0001 => 1111
0010 => 1110
0100 => 1100
1000 => 1000

此外:

0101 => 1101

正如你所看到的,我需要在最后一次' 1之后填写#1;但我事先并不知道最后一个' 1' ;是

2 个答案:

答案 0 :(得分:1)

也许像

unsigned int data;
unsigned int copy = data;
unsigned int shifts = 0;
while (copy > 0) {copy=copy>>1; ++shifts;};
data = data|((1<<shifts)-1);

答案 1 :(得分:1)

不是直接制作必须打开的位掩码,而是更容易制作应该保持不变的位掩码(不是真的,但这样更容易解释) ):将最左边的1复制到右边的所有位:

m = x | (x >> 1);
m |= m >> 2;
m |= m >> 4;
m |= m >> 8;
m |= m >> 16;   // 5 steps for 32 bits, in general log2(width) steps

例如,0101 => 01111000 -> 1111

显然,补码是应该打开的位掩码(除非x为零),所以现在:

if (x != 0)   // this line makes me sad :(
    x |= ~m;

避免长循环,但仍然有一部分不严格的位操作。

不太清楚,使用我的评论中的技巧,观察如果m只有最左边的1个集合,它的否定将是必须在x中设置的位(并且有点已在x中设置,但没关系。所以你得到:

m &= ~(m >> 1);  // see below
x |= -m;

m &= ~(m >> 1)技巧只占m中最左边的1个,这是可能的,因为m是2减1的幂,所以唯一的1可以有0到0它的左边是最左边的1.对于x = 0m = 0,因此显然是m & something = 0 - 不需要特殊情况。在x设置了最高位并因此m = -1的情况下,虽然最左边的1左边没有零,但是它仍会被右移移入(确保它&#39 ;逻辑移位,而非算术移位)。