Corey Iles
Corey Iles

Reputation: 155

Bit manipulation on large integers out of 'int' range

Ok, so let's start with a 32 bit integer:

int big = 536855551; // 00011111111111111100001111111111

Now, I want to set the last 10 bits to within this integer:

int little = 69; // 0001101001

So, my approach was this:

big = (big & 4294966272) & (little)

where 4294966272 is the first 22 bits, or 11111111111111111111110000000000.

But of course this isn't supported because 4294966272 is outside of the int range of 0x7FFFFFFF. Also, this isn't going to be my only operation. I also need to be able to set bits 11 through 14. My approach for that (with the same problem) was:

big = (big & 4294951935) | (little << 10)

So with the explanation out of the way, here is what I'm doing as alternative's for the above:

1: ((big >> 10) << 10) | (little)
2: (big & 1023) | ((big >> 14) << 14) | (little << 10)

I don't feel like my alternative's are the best, efficient way I could go. Is there any better ways to do this?

Sidenote: If C# supported binary literals, '0b', this would be a lot prettier.

Thanks.

Upvotes: 1

Views: 179

Answers (2)

Ian
Ian

Reputation: 30813

Bit shift is usually faster compared to bit-shift + mask (that is, &). I have a test case for it.

You should go with your first alternative.

1: ((big >> 10) << 10) | (little)

Just beware of a little difference between unsigned and signed int when it comes to bit-shifting.

Alternatively, you could define big and little as unsigned. Use uint instead of int.

Upvotes: 2

Rob
Rob

Reputation: 27357

4294966272 should actually be -1024, which is represented as 11111111111111111111110000000000.

For example:

int big = 536855551; 
int little = 69;
var thing = Convert.ToInt32("11111111111111111111110000000000", 2);
var res = (big & thing) & (little);

Though, the result will always be 0

00011111111111111100001111111111
&
00000000000000000000000001101001
&
11111111111111111111110000000000

Upvotes: 2

Related Questions