比特操作-不确定我的比特掩码逻辑



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

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

答案取决于如何组合标准。有两种最简单的情况。

任何匹配或组合您设置的任何标志都将添加匹配项,越多的标志越多的匹配项。

在这种情况下,所有重置标志(0x0000)将永远不匹配。这意味着不符合任何标准。

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

Match是这样实现的:0!=(filter & criteria)其中CCD_ 9是要过滤的标准的集合,而CCD_。

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

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

设置的所有标志将导致最少的匹配。如果您有互斥条件(一个设置,然后其他重置),则所有条件都将导致不匹配。

E。g.你的旗帜:FLAG_LOGINFLAG_NOLOGIN。用户可能已登录,也可能未登录,因此永远不会满足BOTH条件,并且FLAG_LOGIN+FLAG_NOLOGIN永远不会匹配,但0在任何情况下都会匹配,因为没有设置任何条件。

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

如果您的标志是1 | 4,而对象具有1 | 8,则第一种情况将匹配(因为满足1标准,一个就足够了),而第二种情况将不匹配(不满足4标准,但您需要14)。

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

最新更新