我有一个决策树,它使用位总和来确定分支。
例如: 如果我们有规则:1,2,4,8,16 总和由下式确定:如果为真则为sum + = ruleId。
分支功能,而不是:
if(sum == 23) =>
else if(sum == 15) =>
使用按位AND:
if(sum & 23 == 23) =>
else if(sum & 15 == 15) =>
使用按位AND和==?
之间有什么区别我需要做的是生成List<Tuple<int,boo>>
,这将导致给定的结果评估为真。我的想法是:
对于23,例如:
1 && 2 && 4 && 8 && !16
会使其评估为真。但是,按位AND会对此产生什么影响?我需要更改哪些内容才能正确输出会使其成为真的表达式?
答案 0 :(得分:3)
使用按位AND和==?
之间有什么区别
好==
检查这两个值是否相等,简单。按位AND计算位匹配的值。当这与equals检查结合使用时,您有效地检查sum
是否具有与23
使用的相同位。
如果您将这些位写下来更容易理解,请说sum = 31
:
0001 1111 // (sum 31)
& 0001 0111 // (23)
= 0001 0111 // (only set 1 if *both* are 1)
请注意,您的结果与23
相同,因此当您执行(sum & 23) == 23
时,您会获得true
。其目的是检查是否设置了特定位。在23
的情况下,您正在检查是否设置了位16,4,2和。
"C# Bit Flags"
是一个有用的搜索字词。
注意,需要在按位AND周围使用括号,因为优先顺序将首先尝试评估==
:
if((sum & 23) == 23)
这纯粹是猜测你可能想要实现什么,但是如果你试图执行已设置的每个规则,那么你可能想要这样的东西:
if((sum & 1) == 1)
ExecuteRule1();
if((sum & 2) == 2)
ExecuteRule2();
if((sum & 4) == 4)
ExecuteRule4();
if((sum & 8) == 8)
ExecuteRule8();
if((sum & 16) == 16)
ExecuteRule16();
使用此代码,在sum = 23
的情况下,它将执行规则1,2,4和16.但是将跳过规则8.
答案 1 :(得分:2)
为什么要使用按位操作?在你提到的特定情况下,它不重要(只要你将AND包括在像musefan提到的那些parens中)。
但是,如果某些事情略有不同会发生什么?例如,如果新开发人员稍后出现并且必须添加案例,并且不了解其工作原理。他们添加下一位(32或100000)并将其检查添加到if
的底部:
if((sum & 23) == 23) =>
else if((sum & 15) == 15) =>
//...
else if((sum & 31) == 31) =>
会发生什么?
好吧,31二进制&amp; (按位AND)23二进制:
11111
10111
-----
10111
哦,哦!评估为真!而且,由于他们不知道更好,将其添加到底部,23首先评估为TRUE,而从未评估31。
所以,这成了你意图的问题。如果这是预期的行为(我对此表示怀疑),那么您可以使用按位操作,并且您始终知道如果您正在检查(例如23),那么您需要检查设置这些特定位,而不是它们是唯一设置的位。如果您想知道是否只设置了23中的所有位,请使用(sum == 23)。
答案 2 :(得分:0)
只有当总和等于您要测试的值时,等于运算符才会成立。按位&amp;&amp; check将确保该值所代表的所有位都设置在您的值中。
例如
sum = 23(10111),则sum == 23将为真,sum&amp; 23 == 23。
sum = 25(11001),则sum == 23将为false,但sum&amp; 23现在返回17。
11001
& 10111
======
10001 (17)
答案 3 :(得分:0)
当您选择多个位时,需要进一步比较(如==)。因此
if (sum & 020)
精确选择一位。无论是打开还是关闭。
if (sum & 017)
选择最后四位,但如果设置了这些位,则评估为真。
if ((sum & 017) == 017)
选择最后四位,并且必须为表达式设置所有位才为真。
但是,这些测试都没有查看可能设置的其他位。如果你想断言某些位被设置而其他位不被置位,那么你会得到更复杂的测试:
if ((sum & 017) == 017 && !(sum & 060))
在某些时候,你会越过那里更清楚地表达你进行相等比较的意图而不是位掩码。
顺便说一句,你会注意到我正在使用八进制常量。 八位或十进制更容易使用和维护位掩码(IMO)。