I have a UInt32
variable like 3238844000.
Now I want to get the first two bits of this number and the 6 bits after the first two bits. Both bits should be int.
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^
and
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^^^^^
For accessing a specific bit, you can use Shift Operators . If it is always a 1 that you are going to reset, then you could use an & operation. But, if it can also take 0 value, then & operation will fail as 0 & 1 = 0 . You could use | (OR) during that time.
How to extract 'k' bits from a given position 'p' in a number? Examples: Input : number = 171 k = 5 p = 2 Output : The extracted number is 21 171 is represented as 10101011 in binary, so, you should get only 10101 i.e. 21.
Setting a bitUse the bitwise OR operator ( | ) to set a bit. number |= 1UL << n; That will set the n th bit of number . n should be zero, if you want to set the 1 st bit and so on upto n-1 , if you want to set the n th bit.
To set any bit we use bitwise OR | operator. As we already know bitwise OR | operator evaluates each bit of the result to 1 if any of the operand's corresponding bit is set (1).
Update 2:
The simplest (and also the fastest) way for this case turns out to be by purely using the bitwise-shift operators
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input << 2) >> 26); //the simplest and the fastest way
I have heard before that bitwise-shift operations tend to be faster. But today, out of curiosity*, I really compared the performance between bitwise-shift + mask ((int)((input & mask2) >> 24)
) with bitwise-shift alone ((int)((input << 2) >> 26)
). bitwise-shift alone operation is approximately faster by 10%-15%.
This is the result I got:
[2016-01-20 04:01:26.638 UTC] shift-mask: 235 ms shift-only: 199 ms
[2016-01-20 04:01:30.402 UTC] shift-mask: 233 ms shift-only: 200 ms
[2016-01-20 04:01:31.265 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:32.116 UTC] shift-mask: 227 ms shift-only: 199 ms
[2016-01-20 04:01:32.850 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:33.584 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:34.280 UTC] shift-mask: 263 ms shift-only: 214 ms
[2016-01-20 04:01:35.055 UTC] shift-mask: 229 ms shift-only: 201 ms
[2016-01-20 04:01:36.996 UTC] shift-mask: 234 ms shift-only: 201 ms
[2016-01-20 04:01:37.933 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:38.353 UTC] shift-mask: 222 ms shift-only: 196 ms
[2016-01-20 04:01:38.798 UTC] shift-mask: 233 ms shift-only: 211 ms
[2016-01-20 04:01:39.246 UTC] shift-mask: 235 ms shift-only: 213 ms
[2016-01-20 04:01:39.668 UTC] shift-mask: 223 ms shift-only: 198 ms
[2016-01-20 04:01:41.102 UTC] shift-mask: 234 ms shift-only: 200 ms
[2016-01-20 04:01:41.524 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:41.948 UTC] shift-mask: 223 ms shift-only: 200 ms
[2016-01-20 04:01:42.373 UTC] shift-mask: 224 ms shift-only: 200 ms
[2016-01-20 04:01:43.521 UTC] shift-mask: 233 ms shift-only: 197 ms
[2016-01-20 04:01:44.272 UTC] shift-mask: 237 ms shift-only: 216 ms
[2016-01-20 04:01:44.909 UTC] shift-mask: 231 ms shift-only: 196 ms
[2016-01-20 04:01:45.353 UTC] shift-mask: 230 ms shift-only: 213 ms
[2016-01-20 04:01:45.850 UTC] shift-mask: 237 ms shift-only: 207 ms
[2016-01-20 04:01:46.276 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:47.074 UTC] shift-mask: 234 ms shift-only: 203 ms
[2016-01-20 04:01:47.718 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:48.144 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:48.567 UTC] shift-mask: 225 ms shift-only: 198 ms
[2016-01-20 04:01:48.994 UTC] shift-mask: 225 ms shift-only: 199 ms
[2016-01-20 04:01:49.429 UTC] shift-mask: 223 ms shift-only: 211 ms
[2016-01-20 04:01:49.860 UTC] shift-mask: 232 ms shift-only: 198 ms
[2016-01-20 04:01:50.284 UTC] shift-mask: 225 ms shift-only: 199 ms
Note: each experiment is done for (5,000,000 x 100) operations.
*remembering my old days dealing with micro-controllers... ;)
Original:
Just like how you find binary representation for your UInt32
, you should find the right bitwise mask in its binary representation too:
uint mask1 = 0xC0000000; //1100 0000 0000 0000 0000 0000 0000 0000
uint mask2 = 0x3F000000; //0011 1111 0000 0000 0000 0000 0000 0000
And then use them with bitwise-and operator
To get the first two bits, you could simply use the mask like this:
uint val = input & mask1; //should give you the first two bits, the rests are zero
And to get the next 6 bits:
uint val2 = input & mask2; //similarly, should give you only the six bits in the position which you want
If you need them in int
, then simply cast them:
int val = (int)(input & mask1);
int val2 = (int)(input & mask2);
And if you want to put the results in the LSB (the least significant byte
, the rightmost 8-bit
in this case), use bitwise right shift operator:
int val = (int)((input & mask1) >> 30); //30 bits are 0
int val2 = (int)((input & mask2) >> 24); //24 bits are 0
Update:
As for the above shifted version, actually, you could also simply bitwise right shift the first one and do almost similarly for the second, except that it would require a bitwise mask of 0x3F
(0011 1111
) to clear up the unwanted first two bits.
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input >> 24) & 0x3F); //the simpler way
What happen to them in the bit-representation is as follow (I give comments to ease following the logical flow):
The first one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 30 //bitwise right shift by 30
0000 0000 0000 0000 0000 0000 0000 0011 //you get only the first two bits, the rests are all replaced by 0
The second one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 24 //bitwise right shift by 24
0000 0000 0000 0000 0000 0000 1100 0001
0011 1111 //this is 0x3f
--------------------------------------- & //this is bitwise-and
0000 0000 0000 0000 0000 0000 0000 0001 //you only get the 6 bits which you want
Thus you will get 3 (0000 0000 0000 0000 0000 0000 0000 0011)
for your first value, and get 1 (0000 0000 0000 0000 0000 0000 0000 0001)
for your second value.
Along with following the example above, I think you can get the idea on how to do this on many other different cases too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With