Bitwise,bitmasking:这里有什么问题?

时间:2011-06-05 20:15:11

标签: c++ bitmask

我想通过位掩码跟踪一些选项,并借用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)?

5 个答案:

答案 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;