开发者

Concatenating two bit patterns

开发者 https://www.devze.com 2023-02-18 03:47 出处:网络
I need to merge two variables. They both are unsigned ints. First: 11000000 Second: 11111010000 Desired output:

I need to merge two variables. They both are unsigned ints.

  • First: 11000000
  • Second: 11111010000

Desired output: 11011111010000

In words: I need to put all the 1 followed by one 0 (in first number) in front of the whole second number. The only think that come to my mind is, to bit shift the first number to the left as many as the length of the second is. And than sum it. But i don't know the length. Though it probably could be found, isn't there a开发者_如何学C better easier way?

Thx


Here's a solution which runs in constant time:

You can compute the position of the first 1-bit of x by (int)(log(x)/log(2)).

Furthermore, you can compute the number of trailing zeros of x by a neat trick shown here: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup

Hence, your program might look something like this:

int x, y;
int lookuptable[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25,
                        17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 
                        12, 18, 6, 11, 5, 10, 9 };

int tail_x = lookuptable[(((x & -x) * 0x077CB531U)) >> 27];
int size_y = (int)(log(y) / log(2)) + 1;

if (tail_x - size_y <= 0) {
        x <<= size_y - tail_x + 1;
} else {
        x >>= tail_x - size_y - 1;
}       

x |= y;

Now, x contains the result of appending y to x as specified by the OP. Note that you need slight adjustments for non 32-bit machines.


bit shift the first to the right until you have a series of 1's with no trailing 0. then bit shift it to the left for the "length" of the second plus 1 (really the amount of bits after and including the first 1) and then OR them together, don't sum or else bugs could arise.


Determining if an integer is a power of 2

unsigned int v; // we want to see if v is a power of 2 bool f; // the result goes here

f = (v & (v - 1)) == 0; Note that 0 is incorrectly considered a power of 2 here. To remedy this, use: f = v && !(v & (v - 1));

so to see if v is 1 less than a power of 2 we add one to v (v + 1) & v) == 0

(copy + 1) & copy) != 0

so using Jon's answer and replaceing copy!=0 with (copy + 1) & copy) != 0 will trim until theres a int with a series of 1's at the end. copy's scope will need to be outside of that for loop, and the result will be (copy << (cBitsFirst + 1)) | second;

unsigned int first, second; // initialize these somehow
unsigned int result = 0;
int cBitsFirst = 0;
unsigned int copy;
for (copy; (copy + 1) & copy) != 0; copy >>= 1) {//stop when there is series of 0's followed by a series of 1's
    ++cBitsFirst;
}

result = (copy << (log2(second)+1) | second;//the plus one gives the 0 back
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号