Как использовать его в С++?
когда это полезно использовать?
Пожалуйста, дайте мне пример проблемы, в которой используется битмаска, как она работает.
Спасибо!
Как использовать битмаску?
Ответ 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
Для понимания бит-полей вам нужно работать с пониманием двоичного представления чисел и логических операторов.