Получить конкретный бит от uint32
У меня есть переменная UInt32
типа 3238844000.
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^
И
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^^^^^
1 ответ:
Обновление 2:
самый простой (а также самый быстрый) способ для этого случая оказывается чисто с использованием операторов побитового сдвига
Я уже слышал раньше, что операции с побитовым сдвигом, как правило, выполняются быстрее. Но сегодня, из любопытства*, я действительно сравнил производительность между bitwise-shift + mask (int val = (int)(input >> 30); // performs the same int val2 = (int)((input << 2) >> 26); //the simplest and the fastest way
(int)((input & mask2) >> 24)
) и только с помощью bitwise-shift ((int)((input << 2) >> 26)
). операция только с побитовым сдвигом примерно быстрее на 10%-15%.Вот результат, который я получил:
Примечание: каждый эксперимент выполняется для (5 000 000 x 100) операций.[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
*вспоминая свои старые дни, когда я имел дело с микроконтроллерами... ;)
Оригинал:
Точно так же, как вы находите двоичное представление для вашего
UInt32
, вы должны найти правильную побитовую маску в еедвоичном представлении :uint mask1 = 0xC0000000; //1100 0000 0000 0000 0000 0000 0000 0000 uint mask2 = 0x3F000000; //0011 1111 0000 0000 0000 0000 0000 0000
, а затем использовать их с побитово-и оператор
Чтобы получить первые два бита, вы можете просто использовать маску следующим образом:
uint val = input & mask1; //should give you the first two bits, the rests are zero
И получить следующие 6 битов:
uint val2 = input & mask2; //similarly, should give you only the six bits in the position which you want
Если они вам нужны в
int
, то просто бросьте их:int val = (int)(input & mask1); int val2 = (int)(input & mask2);
И если вы хотите поместить результаты в LSB (наименее значимый
byte
, самый правый8-bit
в этом случае), используйте побитовый оператор сдвига вправо :int val = (int)((input & mask1) >> 30); //30 bits are 0 int val2 = (int)((input & mask2) >> 24); //24 bits are 0
Обновление:
Что касается вышеупомянутой сдвинутой версии, на самом деле, вы можно также просто побитово сдвинуть вправо первый и сделать почти то же самое для второго, за исключением того, что для этого потребуется побитовая маска
0x3F
(0011 1111
) чтобы убрать ненужные первые два бита.int val = (int)(input >> 30); // performs the same int val2 = (int)((input >> 24) & 0x3F); //the simpler way
То, что происходит с ними в битовом представлении, выглядит следующим образом (я даю комментарии, чтобы облегчить следование логическому потоку):
Таким образом, вы получите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
3 (0000 0000 0000 0000 0000 0000 0000 0011)
для вашего первого значения и получите1 (0000 0000 0000 0000 0000 0000 0000 0001)
для вашего второго значения.Наряду с выполнением пример выше, я думаю, вы можете получить представление о том, как это сделать на многих других различных случаях тоже.