比较位和时按位与有什么影响?
What effect does a bitwise AND have when comparing bit sums?
我有一个使用位和来确定分支的决策树。
例如:
如果我们有规则:1,2,4,8,16
总和由以下因素确定:如果为真,则总和 += ruleId.
分支函数,而不是做:
if(sum == 23) =>
else if(sum == 15) =>
使用按位与:
if(sum & 23 == 23) =>
else if(sum & 15 == 15) =>
使用按位与和 == 有什么区别?
我需要做的是生成一个 List<Tuple<int,boo>>
来引导给定结果评估为真。我的想法是:
对于 23,例如:
1 && 2 && 4 && 8 && !16
将使它的计算结果为真。但是,按位AND对此有什么影响呢?我需要更改什么才能正确输出使其为真的表达式?
仅当总和等于您要测试的值时,相等运算符才会为真。按位 && 检查将确保由该数字表示的所有位都设置在您的值中。
例如
sum = 23 (10111),则 sum == 23 为真,sum & 23 == 23 也为真。
sum = 25 (11001),那么 sum == 23 会是 false,但是 sum & 23 现在 returns 17.
11001
& 10111
======
10001 (17)
What is the difference between using the bitwise AND and the == ?
嗯==
检查两个值是否相等,简单。按位与计算位匹配的值。当这与等于检查结合使用时,您实际上是在检查 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 和 1。
如果您想了解更多信息,"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。
当您选择了多个位时,您需要进一步比较(如==)。于是
if (sum & 020)
恰好选择一位。开启或关闭。
if (sum & 017)
选择最后四位,但如果设置了这些位中的任何一位,则计算结果为真。
if ((sum & 017) == 017)
选择最后四位,必须设置所有位才能使表达式为真。
但是,none 这些测试会查看可能设置的其他位。如果您想断言某些位已设置而其他位未设置,您会得到更复杂的测试:
if ((sum & 017) == 017 && !(sum & 060))
在某些时候,您越过了一个比位掩码更清楚地表达您进行相等比较的意图的地方。
顺便说一句,您会注意到我使用的是八进制常量。
对于位掩码 (IMO),八进制或十进制更易于使用和维护。
为什么要使用位运算?在您提到的特定情况下,这无关紧要(只要您将 AND 包裹在像 提及的括号中)。
但是,如果有些地方略有不同怎么办?例如,如果一个新的开发人员后来出现并且必须添加一个案例,并且不了解它是如何工作的。他们添加下一位(32 或 100000)并将他们的支票添加到 if
的 bottom:
if((sum & 23) == 23) =>
else if((sum & 15) == 15) =>
//...
else if((sum & 31) == 31) =>
会发生什么?
嗯,二进制 31 &(按位与)二进制 23:
11111
10111
-----
10111
呃哦!评估为真!由于他们不知道更好,将其添加到底部,因此 23 首先评估为 TRUE,而 31 永远不会评估。
所以,这就变成了你的意图的问题。如果这是预期的行为(我对此表示怀疑),那么您可以使用按位操作,并且您将始终知道如果您正在检查,例如,23,您正在检查那些特定的位是否已设置,而不是它们是唯一的位集。如果您想知道是否仅设置了 23 中的所有位,请使用 (sum == 23)。
我有一个使用位和来确定分支的决策树。
例如: 如果我们有规则:1,2,4,8,16 总和由以下因素确定:如果为真,则总和 += ruleId.
分支函数,而不是做:
if(sum == 23) =>
else if(sum == 15) =>
使用按位与:
if(sum & 23 == 23) =>
else if(sum & 15 == 15) =>
使用按位与和 == 有什么区别?
我需要做的是生成一个 List<Tuple<int,boo>>
来引导给定结果评估为真。我的想法是:
对于 23,例如:
1 && 2 && 4 && 8 && !16
将使它的计算结果为真。但是,按位AND对此有什么影响呢?我需要更改什么才能正确输出使其为真的表达式?
仅当总和等于您要测试的值时,相等运算符才会为真。按位 && 检查将确保由该数字表示的所有位都设置在您的值中。
例如
sum = 23 (10111),则 sum == 23 为真,sum & 23 == 23 也为真。
sum = 25 (11001),那么 sum == 23 会是 false,但是 sum & 23 现在 returns 17.
11001
& 10111
======
10001 (17)
What is the difference between using the bitwise AND and the == ?
嗯==
检查两个值是否相等,简单。按位与计算位匹配的值。当这与等于检查结合使用时,您实际上是在检查 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 和 1。
"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。
当您选择了多个位时,您需要进一步比较(如==)。于是
if (sum & 020)
恰好选择一位。开启或关闭。
if (sum & 017)
选择最后四位,但如果设置了这些位中的任何一位,则计算结果为真。
if ((sum & 017) == 017)
选择最后四位,必须设置所有位才能使表达式为真。
但是,none 这些测试会查看可能设置的其他位。如果您想断言某些位已设置而其他位未设置,您会得到更复杂的测试:
if ((sum & 017) == 017 && !(sum & 060))
在某些时候,您越过了一个比位掩码更清楚地表达您进行相等比较的意图的地方。
顺便说一句,您会注意到我使用的是八进制常量。 对于位掩码 (IMO),八进制或十进制更易于使用和维护。
为什么要使用位运算?在您提到的特定情况下,这无关紧要(只要您将 AND 包裹在像
但是,如果有些地方略有不同怎么办?例如,如果一个新的开发人员后来出现并且必须添加一个案例,并且不了解它是如何工作的。他们添加下一位(32 或 100000)并将他们的支票添加到 if
的 bottom:
if((sum & 23) == 23) =>
else if((sum & 15) == 15) =>
//...
else if((sum & 31) == 31) =>
会发生什么?
嗯,二进制 31 &(按位与)二进制 23:
11111
10111
-----
10111
呃哦!评估为真!由于他们不知道更好,将其添加到底部,因此 23 首先评估为 TRUE,而 31 永远不会评估。
所以,这就变成了你的意图的问题。如果这是预期的行为(我对此表示怀疑),那么您可以使用按位操作,并且您将始终知道如果您正在检查,例如,23,您正在检查那些特定的位是否已设置,而不是它们是唯一的位集。如果您想知道是否仅设置了 23 中的所有位,请使用 (sum == 23)。