如何使用位掩码
How can I use a bitmask?
如何在C++中使用它?什么时候使用有用?
使用位掩码来查看其实际工作方式的问题示例是什么?
简而言之,位掩码有助于操纵多个值的位置。这里有一个很好的例子;
位标志是一种将多个不互斥的值存储在一个变量中的方法。你可能以前见过它们。每个标志都是一个位位置,可以设置为打开或关闭。然后,您可以为每个位位置定义一堆位掩码#,这样您就可以轻松地操作它:
#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 assigning a value will clobber any other flags, so you
// it should generally only use the = operator when initialising variables.
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))
...
你也可以搜索C++技巧。
当您想在单个数据值中存储(并随后提取)不同的数据时,位掩码是"有用的"。
我以前使用过的一个示例应用程序是,假设您将彩色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);
假设我有32位ARGB值,每个通道有8位。我想用另一个alpha值替换alpha组件,例如0x45
unsigned long alpha = 0x45
unsigned long pixel = 0x12345678;
pixel = ((pixel & 0x00FFFFFF) | (alpha << 24));
掩码将前8位变为0,旧的alpha值在这里。alpha值向上移动到它将采用的最终位位置,然后将其"或"运算为屏蔽像素值。最终结果是0x45345678,它被存储到像素中。
当您想在一个数字中对多层信息进行编码时,会使用比特掩码。
因此(假设unix文件权限),如果您想存储3个级别的访问限制(读、写、执行),您可以通过检查相应的位来检查每个级别。
rwx
---
110
底座2中的110转换为底座10中的6。
因此,您可以很容易地检查是否允许某人读取文件,例如,通过在权限字段中键入所需的权限。
伪码:
PERM_READ = 4
PERM_WRITE = 2
PERM_EXEC = 1
user_permissions = 6
if ((user_permissions & PERM_READ) == PERM_READ) then
// this will be reached, as 6 & 4 is true
fi
您需要对数字的二进制表示和逻辑运算符有深入的了解,才能理解位字段。
相关文章:
- 使用二进制掩码 C++ ITK 获取感兴趣区域
- 递归函数,用于使用位掩码 c++ 显示集合的所有子集
- 使用位掩码生成排列
- 使用DHCP获取IP地址,网关,掩码和广播信息
- 使用 CPP 中的值和掩码计算导数
- 使用enum类的符合C++11标准的位掩码
- 如何将模板缓冲区与 alpha 掩码一起使用
- C++使用密钥和掩码对字符进行加密
- 使用位掩码生成素数导致程序崩溃
- 在将uint64_t截断为uint8_t[I]时,我应该使用位掩码吗
- 仅使用位掩码确定偏移量
- 使用掩码计算 uint512 的位
- 如何使用带有俄语字母的QLineEdit掩码
- 占位符文本 文本字段中的文本在使用输入掩码时不显示
- 如何使用位掩码
- 使用位掩码重建整数
- 如何在不使用位掩码的情况下设置Integer中的位
- 在Blackberry 10 Cascades中,有一种方法可以使用图像掩码或alpha通道更改Blackberry C
- 如何使用BestOf2NearestMatcher匹配掩码
- 在c++中使用由iOS本地库公开的C位掩码(匿名enum)