我想通过位掩码跟踪一些选项,并借用this answer中的位掩码值,但它们似乎不能一起工作。
#include <iostream>
#define OP1 0x00003FFFUL
#define OP2 0x00007FFFUL
#define OP3 0x0000FFFFUL
int main() {
unsigned long params = 0; // .
params |= OP3;
if ( (params & OP1) == OP1)
std::cout << "Whoa. Lame masking\n";
}
是类型问题,还是这个方法一次不能用于保存多个选项(OP1,OP2和OP3都希望保持同一个params
)?
答案 0 :(得分:4)
对于选项,您应该使用其他蒙版,不重叠的蒙版,例如:
#define OP1 0x000000FUL
#define OP2 0x00000F0UL
#define OP3 0x0000F00UL
或(在这种情况下,您将能够存储与可用位一样多的选项):
#define OP1 0x0000001UL
#define OP2 0x0000002UL
#define OP3 0x0000004UL
//ETC...
你的面具永远不会正常工作,因为如果设置了OP3,那么OP1和OP2将被包含(如果你使用OP2则会一样,那么暗示OP1):
FFFF = 1111111111111111
& 3FFF = 0011111111111111
-----------------------
3FFF = 0011111111111111
您粘贴的示例中的掩码旨在推断UL的最后几位。
答案 1 :(得分:2)
你认为0xF&amp;的价值是什么? 0x3?
答案 2 :(得分:2)
它有所有'选项'。问题是,OP1,OP2和OP3中的位重叠。 OP3还设置了OP1和OP2的所有位。因此,OP3和OP1将等于OP1,OP3和OP2将等于OP2。因此,混乱。如果OP1 = 1,OP2 = 2,OP3 = 4,情况就不是这样。然后你还必须将标志设置为
params |= OP1 | OP2 | OP3
但如果您需要OP1,OP2和OP3,那么您的位掩码代码就没有问题。
答案 3 :(得分:2)
这个实现可能很奇怪,除非你有一些其他的东西没有显示(似乎不太可能,因为它是从另一个问题中获取)。一个更好的解决方案可能是枚举你的位掩码。类似的东西:
enum values {
aaa = 1 << 0,
bbb = 1 << 1,
ccc = 1 << 2,
ab = aaa | bbb,
ac = aaa | ccc,
abc = aaa | bbb | ccc,
bc = bbb | ccc, };
然后可以像:
一样使用unsigned int var = abc;
if (var & aaa) {
cout << "OK";
}
输出'OK'
这为您提供了您可能需要的重叠值,同时还明确定义了它们之间的关系。如果你想获得更多的爱好者,你可以做到:
namespace blah {
enum values {
aaa = 1 << 0,
bbb = 1 << 1,
ccc = 1 << 2,
ab = aaa | bbb,
ac = aaa | ccc,
abc = aaa | bbb | ccc,
bc = bbb | ccc,
};
}
这将使您能够像以下一样使用它:
unsigned int var = blah::abc;
if (var & blah::aaa) {
cout << "OK";
}
再次输出'OK'
如果你使用uint的全宽和标志的许多组合(它不会使你的主命名空间混乱),这就变得很好。
答案 4 :(得分:1)
你没有初始化params。
尝试:
unsigned long params = 0;