为什么要将一个标志与位掩码和标志的按位AND结果进行比较?

时间:2017-07-06 11:45:23

标签: bit-manipulation bitmask

作为“How to use bitmask”的后续内容:当我想测试某个位掩码中是否设置了某个标志时,我通常只会通过使用bitwise AND来执行此操作:

if(bitmask & flag) { …

然而,我经常看到这样的事情:

if((bitmask & flag) == flag) { …

这是我在强类型和弱类型语言中观察到的东西,它排除了对类型铸造灾难的某种预防。我可以提出的唯一两种测试不相同的情况是,如果flag碰巧实际上设置了多个位,那么所有都必须在{ {1}}通过条件。是全是还是我在这里遗漏了什么?

额外奖励:编译器是否有办法识别在运行时最多设置一位的bitmask并优化(可能是虚假的)比较?

1 个答案:

答案 0 :(得分:2)

正如您所指出的,这两个条件并不相同。检查(bitmask & flag) 1 正在检查flag中是否设置了 bitmask中设置的任何位,(bitmask & flag) == flag检查是否设置了flag中的所有位。

如果只有一个位设置,你可能也会看到第二种形式,而不是像Java那样没有从整数类型到布尔值的隐式转换的第一种形式。这些语言中第一次检查的确切等价物为(bitmask & flag) != 0,即使检查单个标志,该形式也可能更具规范性。

就实际生成的代码而言,它几乎都是学术性的。

对于编译时已知的 2 标志,编译器可以看到该标志只有一位,两种表单通常都会被编译为identical code - 请参阅{{该链接中有1}}和fixedA个函数。

对于具有未知标志的函数,如上所述,表单不等效,因此代码不同(请参阅fixedBunknownA函数)但性能差异非常小。

1 或者,等效地,B在没有从整数类型到布尔值的隐式转换的语言中。

2 重要的是,这包括接受变量标志的函数,但调用者使用常量标志并且函数内联的函数。