Побитовое ИЛИ констант - PullRequest
9 голосов
/ 30 мая 2010

Читая некоторую документацию здесь , я наткнулся на это:

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;

Понятия не имею, как это работает. Я читал о побитовых операторах в C, но я не понимаю, как вы можете поместить три (или более!) Константы в одно целое, и позже сможете как-то извлечь их обратно из целого? Копаясь дальше в документации, я также нашел это, которое, вероятно, связано:

typedef enum {
   kCFCalendarUnitEra = (1 << 1),
   kCFCalendarUnitYear = (1 << 2),
   kCFCalendarUnitMonth = (1 << 3),
   kCFCalendarUnitDay = (1 << 4),
   kCFCalendarUnitHour = (1 << 5),
   kCFCalendarUnitMinute = (1 << 6),
   kCFCalendarUnitSecond = (1 << 7),
   kCFCalendarUnitWeek = (1 << 8),
   kCFCalendarUnitWeekday = (1 << 9),
   kCFCalendarUnitWeekdayOrdinal = (1 << 10),
} CFCalendarUnit;

Как работают операторы / переменные (1 << 3)? Извините, если это тривиально, но кто-то может просветить меня, объяснив или, возможно, разместив ссылку на хорошее объяснение?

Ответы [ 5 ]

9 голосов
/ 30 мая 2010

По сути, константы представлены только одним битом, поэтому, если у вас есть 32-битное целое число, вы можете разместить в нем 32 константы. Ваши константы должны иметь степень двойки, поэтому для их представления требуется только один «установленный» бит.

Например:

#define CONSTANT_1 0x01 // 0001 in binary
#define CONSTANT_2 0x02 // 0010 in binary
#define CONSTANT_3 0x04 // 0100 in binary

тогда вы можете сделать

int options = CONSTANT_1 | CONSTANT_3; // will have 0101 in binary.

Как видите, каждый бит представляет эту конкретную константу. Таким образом, вы можете использовать двоичное И в своем коде и проверять наличие каждой константы, например:

if (options & CONSTANT_3)
{
    // CONSTANT_3 is set
}

Я рекомендую вам прочитать о бинарных операциях (они работают как операторы LOGICAL, но на битовом уровне), если вы поймете это, это сделает вас немного лучше программиста.

Приветствие.

2 голосов
/ 30 мая 2010

Если вы посмотрите на двоичное число, каждая цифра либо включена (1), либо выключена (0).

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

Возьмите 8-битное значение 156. В двоичном виде это 10011100.

Установленные биты соответствуют битам 7, 4, 3 и 2 (значения 128, 16, 8, 4). Вы можете легко вычислить эти значения с помощью 1 << (position). Итак, 1 << 7 = 128.

1 голос
/ 30 мая 2010

Число 1 представлено как 00000000000000000000000000000001 (1 << n) означает сдвиг представления 1 в 1 на n мест влево Так что (1 << 3) будет 00000000000000000000000000001000 В одном int вы можете иметь 32 параметра, каждый из которых может быть включен или выключен. Опция номер n включена, если n-й бит равен 1 </p>

0 голосов
/ 30 мая 2010

<< - оператор сдвига влево, он сдвигает биты первого операнда влево на количество позиций, указанных в правом операнде (с нулями, приходящими в сдвинутые позиции справа).

В вашем перечислении вы получите значения, которые в eacg имеют другой бит, установленный в 1, поэтому, когда вы создаете что-то вроде unitDate, вы можете позже выяснить, какие флаги он содержит, используя оператор &, например, unitDate & NSMonthCalendarUnit == NSMonthCalendarUnit будет правдой.

0 голосов
/ 30 мая 2010

1 << y в основном то же самое, что и 2 to the power of y

В общем, x << y - это то же самое, что и x multiplied by 2 to the power of y.

В двоичном формате x << y означает перемещение всех битов x влево на y мест, добавление нулей вместо перемещенных битов:

00010 << 2 = 01000

Итак:

1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
...
...