我不确定我的位掩码逻辑

时间:2014-04-29 11:23:37

标签: bit-manipulation flags bitmask bitflags

我有对象,我只想根据不同的标准显示给访问者。 该对象有一个位掩码,我已经定义了以下条件:

const FLAG_ALWAYS   = 0; // always show this item
const FLAG_LOGIN    = 1; // only display to logged in users
const FLAG_NOTLOGIN = 2; // only display to users not logged in
const FLAG_OTHER    = 4; // other criteria
const FLAG_NORTH    = 8; // GeoIP
const FLAG_SOUTH    = 16;

标志的组合当然可以是1+4+162+4

可以在3个条件下显示项目以进行登录:例如:已登录,未登录或两者都有。因此,我需要FLAG_NOTLOGIN

我对FLAG_ALWAYS感到困惑......应该是0,还是应该涵盖4095之类的所有其他标志?

或者我应该删除FLAG_NOTLOGIN

2 个答案:

答案 0 :(得分:1)

FLAG_ALWAYS应该是所有其他标志的组合,它不应该为零。无需删除FLAG_NOTLOGIN。

答案 1 :(得分:1)

答案取决于您如何组合标准。有两个最简单的案例。

任何匹配,或组合。您设置的任何标记都会添加匹配,更多标记会更多匹配。

在这种情况下,所有标志复位(0x0000)将永远匹配。这意味着没有符合标准。

所有标志设置(0xFFFF)将导致大多数匹配。如果您有免费标准(其中一个已设定),则标准将始终匹配。

匹配是这样实现的:0!=(filter & criteria) 其中filter是要过滤的标准集,criteria是在几个条件下设置的相同标志。

所有匹配,AND组合。您设置的任何标记都会过滤掉一些匹配,更多标记会少匹配。

在这种情况下,重置的所有标志将始终匹配。

设置的所有标志都会导致最少匹配。如果你有相互排斥的标准(一组,那么其他人重置)当所有标准都没有匹配时。

电子。 G。你的旗帜:FLAG_LOGINFLAG_NOLOGIN。用户可能是登录用户,也不是用户,因此两个条件永远不会满足,FLAG_LOGIN+FLAG_NOLOGIN永远不会匹配,但0在任何情况下都不匹配,因为没有标准设置。

匹配是使用以下公式实现的:0==(all_flags & ~filter & ~criteria),此处filtercriteria与上述相同,all_flags设置为所有使用标志,用于排除比较中未使用的位。 (注意,表达式criteria == (filter & criteria)似乎更明显但是错误,因为当标准中没有设置标志时,它将不会导致匹配。)

如果您的标记为1 | 4且对象具有1 | 8,则第一种情况将匹配(因为符合1条件并且一个就足够了)并且第二种情况不匹配({ {1}}条件未达到,但您需要41)。