Самый быстрый способ чтения левого бита из unsigned int (C ++)? - PullRequest
5 голосов
/ 27 июля 2010

Какой самый быстрый способ прочитать самый левый бит из unsigned int?

Ответы [ 7 ]

18 голосов
/ 27 июля 2010
i >> (sizeof(unsigned int) * CHAR_BIT - 1)

sizeof, умножение и вычитание будут вычисляться во время компиляции любым разумным компилятором, поэтому это должно стать одной инструкцией сдвига вправо, что примерно так же быстро, как вы получите.

8 голосов
/ 27 июля 2010

Может быть быстрее сдвига во время выполнения, если AND быстрее сдвига:

i & (1 << (sizeof(unsigned int) * CHAR_BIT - 1))
5 голосов
/ 27 июля 2010

В 32-битной системе, использующей любой компилятор, который будет использовать обычный человек, без странных, эзотерических краевых случаев, от которых фанаты C ++, похоже, не могут не волноваться, планета Земля, около 2010 года, звезды не выровнены,обычный день:

if (value & 0x8000000) { ... }
3 голосов
/ 27 июля 2010
#define MSB ~(~0U >> 1 )

разбивая его, предполагая 8 битов int для примера.

0U = 00000000b
~0U = 11111111b
~0U >> 1 = 01111111b
~(~0U >> 1) = 10000000b

затем И это значение с тем, что вы хотите проверить (приведено как unsigned int)

(unsigned int ) a & MSB;
2 голосов
/ 27 июля 2010

Конечно, вы также можете попробовать это:

((int) myUint) < 0 // true if set, otherwise false

И использовать тот факт, что для целых чисел со знаком, самый левый бит установлен для отрицательных чисел.

Это также должно бытьдовольно быстро, так как приведение происходит во время компиляции, и на самом деле его не нужно выполнять - оно просто говорит компилятору использовать подписанные коды операций, а не неподписанные.Поэтому я считаю, что нужно выполнить одну инструкцию (CMP?) ...

0 голосов
/ 28 июля 2010

Как насчет этого?

i >> numeric_limits<unsigned>::digits - 1;
0 голосов
/ 27 июля 2010

Хорошо, это зависит от размера целого числа, порядкового номера и от того, хотите ли вы, чтобы самый левый бит находился в зависимости от ориентации в памяти или самого старшего бита.

Предполагая, что вам нужен старший значащий бит, который на 32-битной машине с прямым порядком байтов (наиболее распространенный тип) будет находиться в четвертом байте из местоположения int s в памяти .:

i & 0x80000000

Теперь регистр является логическим для присутствия бита MSB.

Может быть возможно сдвинуть бит вправо, это может генерировать меньше объектного кода:

i >> (sizeof(i) * CHAR_BIT - 1)

Update0

Может быть, некоторые не знают, что я имею в виду выше. На примере архитектуры, которую я привел, вы также можете сделать это:

((unsigned char *)&i)[3] >> 7
((unsigned char *)&i)[3] & 0x80
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...