Что означает «(int) значение & 0x1, (int) значение & 0x2, (int) значение & 0x4, (int) значение & 0x8»?

11

код

«Значение» варьируется от 0 до 15 (его возможные значения). Когда эти 4 условия "если" будут выполнены? Если my (int) value = 2, значит ли это 0010?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }
Шон Маккарти
источник
3
Это битовые маски, проверяющие отдельные биты value(читается if(value & 0x4)как «3-й бит valueустановлен (= 1)). Поскольку у вас, по-видимому, есть проблемы с пониманием кода, я предполагаю, что он не ваш. Это (и тот факт, что вы не спрашиваете» для обзора) делает этот вопрос не по теме для CR.SE .
Nobody
Для лучшего понимания аналогичный код, который был портирован на C #, будет использовать Enum.HasFlagметод для проверки битов. Смотрите: Enum.HasFlag .
rwong

Ответы:

12

Каждое число может быть выражено как value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...с каждым b, являющимся или 0или 1(это биты представления). Это двоичное представление.

Двоичный AND ( &) принимает каждую из этих bпар и выполняет AND на них. Это имеет следующие выводы:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

Используя степени 2 (которые имеют только один бит), мы можем выделить и проверить отдельные биты:

  • value & 1истинно, когда valueнечетно {1, 3, 5, 7, 9, 11, 13, 15}.

  • value & 2верно, когда value/2нечетное {2, 3, 6, 7, 10, 11, 14, 15}.

  • value & 4верно, когда value/4нечетное {4, 5, 6, 7, 12, 13, 14, 15}.

  • value & 8верно, когда value/8нечетное {8, 9, 10, 11, 12, 13, 14, 15}.

Значение 0x на числах означает, что его следует интерпретировать как шестнадцатеричное число . Это немного излишне, когда вы поднимаетесь только до 0x8, но указывает сопровождающим, что он, вероятно, используется в качестве битовой маски.

чокнутый урод
источник
1
Формулировка может предполагать, что она может быть распространена на все числа, что не соответствует действительности: 8/6является нечетным, а 8&6возвращает ложным.
Sjoerd
@Sjoerd, поэтому я сказал "полномочия 2"
чокнутый урод
5

Эти операторы if проверяют, установлен ли определенный бит value.

0x4Например, шестнадцатеричное значение имеет 3-й бит справа, установленный в, 1а все остальные биты - в 0. Когда вы используете двоичные операторы and и (( &) с двумя оперантами, результат будет иметь все биты, 0кроме тех, которые равны 1 в обоих оперантах.

Поэтому , когда вы делаете расчет value & 0x4, вы либо получить двоичный 00000000или двоичный 00000100, в зависимости от того , или нет 3 - й бит valueявляется 1или 0. Первое вычисляется как false, а второе как true, поэтому блок if выполняется только для значений, в которых установлен 3-й бит.

Philipp
источник
1

Здесь нужно отметить две интересные вещи.

Во-первых, это общий шаблон для проверки каждого из 4 младших битов интегрального значения. Условие if выполняется, если установлен соответствующий бит. Для значения 2 битовая комбинация действительно равна 0010.

Другой, более интересный вопрос: почему (int)актеры? Помимо плохого стиля использования C-приведений в C ++, никакие целочисленные или символьные значения не требуют этого приведения. Значение bool не имеет смысла, значение double / float будет преобразовано во временное целое число, и было бы необычно использовать буквальные значения для проверки перечисления. Это может иметь смысл с указателем, но это будет очень специализированное использование. Вывод: актерский состав не имеет смысла.

david.pfx
источник