Get a specific bit from uint32

I have a UInt32 variable such as 3238844000.

Now I want to get the first two bits of this number and 6 bits after the first two bits. Both bits must be int.

 Decimal: 3238844000 Binary: 11000001000011001101011001100000 ^^ 

and

 Decimal: 3238844000 Binary: 11000001000011001101011001100000 ^^^^^^ 
+5
source share
1 answer

Update 2:

The simplest (as well as the fastest) way for this case is obtained using purely byte 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 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) ) only with bitwise shift ( (int)((input << 2) >> 26) ) one bit shift operation is approximately 10% -15% faster .

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 performed for operations (5,000,000 x 100).

* recalling my old days regarding microcontrollers ...;)


Original:

Just as you find the binary representation for UInt32 , you should find the desired bitmask in your binary representation :

 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 the bitwise operator and

To get the first two bits, you can simply use the mask as follows:

 uint val = input & mask1; //should give you the first two bits, the rests are zero 

And to get the following 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 , just execute them:

 int val = (int)(input & mask1); int val2 = (int)(input & mask2); 

And if you want to put the results in LSB (least significant byte , right 8-bit most 8-bit in this case), use the 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 shifted version above, in fact, you could just just bit the first right offset and do the same for the second, except that you would need a bit mask from 0x3F ( 0011 1111 ) to clear the unwanted first two bits.

 int val = (int)(input >> 30); // performs the same int val2 = (int)((input >> 24) & 0x3F); //the simpler way 

What happens to them in the bit representation, as it should (I give comments to facilitate 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 

So you 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 the above example, I think you can get an idea of ​​how to do this in many other cases.

+12
source

Source: https://habr.com/ru/post/1240832/


All Articles