How to do the bit manipulation when you don't know where the left-most '1' bit is?

为君一笑 提交于 2019-12-12 04:57:31

问题


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

Also:

0101 => 1101

As you can see I need to fill with '1's after the last '1', but I do not know in advance where the last '1' is.


回答1:


Maybe something like

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



回答2:


Instead of directly making the mask of the bits that have to be switched on, it's easier to make the mask of bits that should be unchanged (not really, but it's easier to explain this way): copy the left-most 1 to all bits to the right of it:

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

For example, 0101 => 0111, or 1000 -> 1111.

Clearly the complement of that is the mask of bits that should be turned on (unless x was zero), so now:

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

Avoids a long loop, but still has a part in it that isn't strictly bit-manipulation.

Less clearly, using the trick from my comment, observe that if m only had its left most 1 set, its negation would be the bits that have to be set in x (and a bit that is already set in x, but that's ok). So you get:

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

The m &= ~(m >> 1) trick takes only the leftmost 1 of m, this is possible now because m is a power of two minus 1, so the only 1 that can have a 0 to the left of it is the leftmost 1. In the case of x = 0, m = 0 and therefore obviously m & something = 0 - no special case required. In the case that x has the top bit set and thus m = -1, while there is no zero to the left of the leftmost 1, it gets shifted in by the right shift anyway (make sure it's a logical shift, not an arithmetic shift).



来源:https://stackoverflow.com/questions/25689315/how-to-do-the-bit-manipulation-when-you-dont-know-where-the-left-most-1-bit-i

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