Подтвердить что ты не робот

Как использовать битмаску?

Как использовать его в С++? когда это полезно использовать?
Пожалуйста, дайте мне пример проблемы, в которой используется битмаска, как она работает. Спасибо!

4b9b3361

Ответ 1

Бит-маскирование "полезно" для использования, когда вы хотите хранить (и впоследствии извлекать) разные данные в пределах одного значения данных.

Пример приложения, которое я использовал ранее, предполагает, что вы сохраняете значения RGB цвета в 16-битном значении. Итак, что-то похожее на это:

RRRR RGGG GGGB BBBB

Затем вы можете использовать маскировку битов для извлечения цветовых компонентов следующим образом:

  const unsigned short redMask   = 0xF800;
  const unsigned short greenMask = 0x07E0;
  const unsigned short blueMask  = 0x001F;

  unsigned short lightGray = 0x7BEF;

  unsigned short redComponent   = (lightGray & redMask) >> 11;
  unsigned short greenComponent = (lightGray & greenMask) >> 5;
  unsigned short blueComponent =  (lightGray & blueMask);

Ответ 2

Вкратце битмаска помогает управлять позицией нескольких значений. Здесь есть хороший пример;

Битфлаги - это метод хранения нескольких значений, которые не являются взаимно исключающими из одной переменной. Вы, наверное, видели их раньше. Каждый флаг является битовой позицией, которая может быть установлена ​​или выключена. Затем у вас есть битмаски #defined для каждой позиции бит, чтобы вы могли легко манипулировать им:

    #define LOG_ERRORS            1  // 2^0, bit 0
    #define LOG_WARNINGS          2  // 2^1, bit 1
    #define LOG_NOTICES           4  // 2^2, bit 2
    #define LOG_INCOMING          8  // 2^3, bit 3
    #define LOG_OUTGOING         16  // 2^4, bit 4
    #define LOG_LOOPBACK         32  // and so on...

// Only 6 flags/bits used, so a char is fine
unsigned char flags;

// initialising the flags
// note that assignming a value will clobber any other flags, so you
// should generally only use the = operator when initialising vars.
flags = LOG_ERRORS;
// sets to 1 i.e. bit 0

//initialising to multiple values with OR (|)
flags = LOG_ERRORS | LOG_WARNINGS | LOG_INCOMING;
// sets to 1 + 2 + 8 i.e. bits 0, 1 and 3

// setting one flag on, leaving the rest untouched
// OR bitmask with the current value
flags |= LOG_INCOMING;

// testing for a flag
// AND with the bitmask before testing with ==
if ((flags & LOG_WARNINGS) == LOG_WARNINGS)
   ...

// testing for multiple flags
// as above, OR the bitmasks
if ((flags & (LOG_INCOMING | LOG_OUTGOING))
         == (LOG_INCOMING | LOG_OUTGOING))
   ...

// removing a flag, leaving the rest untouched
// AND with the inverse (NOT) of the bitmask
flags &= ~LOG_OUTGOING;

// toggling a flag, leaving the rest untouched
flags ^= LOG_LOOPBACK;



**

ПРЕДУПРЕЖДЕНИЕ: НЕ используйте оператор равенства (т.е. бит-флагов == битмаска) для тестирования, если флаг установлен - это выражение будет истинным только в том случае, если этот флаг установлен, а все остальные не установлены. Проверка отдельного флага вам нужно использовать и и ==:

**

if (flags == LOG_WARNINGS) //DON'T DO THIS
   ...
if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // The right way
   ...
if ((flags & (LOG_INCOMING | LOG_OUTGOING)) // Test for multiple flags set
         == (LOG_INCOMING | LOG_OUTGOING))
   ...

Вы также можете выполнить поиск С++ Triks

Ответ 3

Скажем, у меня есть 32-разрядное значение ARGB с 8 бит на канал. Я хочу заменить альфа-компонент другим альфа-значением, например 0x45

unsigned long alpha = 0x45
unsigned long pixel = 0x12345678;
pixel = ((pixel & 0x00FFFFFF) | (alpha << 24));

Маска превращает верхние 8 бит в 0, где старое значение альфа. Значение альфа сдвигается до конечных позиций бит, которые он примет, затем OR-ed в значение маскированного пикселя. Конечным результатом является 0x45345678, который сохраняется в пикселях.

Ответ 4

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

Итак (при условии разрешения файлов unix), если вы хотите сохранить 3 уровня ограничения доступа (чтение, запись, выполнение), вы можете проверить каждый уровень, проверив соответствующий бит.

rwx
---
110

110 в основании 2 переводится в 6 в основании 10.

Таким образом, вы можете легко проверить, разрешено ли кому-либо, например. прочитайте файл и введите поле разрешения с требуемым разрешением.

псевдокод:

PERM_READ = 4
PERM_WRITE = 2
PERM_EXEC = 1

user_permissions = 6

if (user_permissions & PERM_READ == TRUE) then
  // this will be reached, as 6 & 4 is true
fi

Для понимания бит-полей вам нужно работать с пониманием двоичного представления чисел и логических операторов.