简体   繁体   English

布尔运算符与位运算符

[英]Boolean operators vs Bitwise operators

I am confused as to when I should use Boolean vs bitwise operators我对什么时候应该使用布尔运算符和按位运算符感到困惑

  • and vs & and vs &
  • or vs | or vs |

Could someone enlighten me as to when do i use each and when will using one over the other affect my results?有人能告诉我什么时候使用每一种以及何时使用一种会影响我的结果吗?

Here are a couple of guidelines:以下是一些指导方针:

  • Boolean operators are usually used on boolean values but bitwise operators are usually used on integer values.布尔运算符通常用于布尔值,但按位运算符通常用于数值。
  • Boolean operators are short-circuiting but bitwise operators are not short-circuiting.布尔运算符是短路的,但按位运算符不是短路的。

The short-circuiting behaviour is useful in expressions like this:短路行为在这样的表达式中很有用:

if x is not None and x.foo == 42:
    # ...

This would not work correctly with the bitwise & operator because both sides would always be evaluated, giving AttributeError: 'NoneType' object has no attribute 'foo' .这对于按位&运算符将无法正常工作,因为总是会评估双方,从而给出AttributeError: 'NoneType' object has no attribute 'foo' When you use the boolean and operator the second expression is not evaluated when the first is False.当您使用布尔运算符and运算符时,当第一个表达式为 False 时,不会计算第二个表达式。 Similarly or does not evaluate the second argument if the first is True.如果第一个参数为 True,则类似or不评估第二个参数。

In theory, and and or come straight from boolean logic (and therefore operate on two booleans to produce a boolean), while & and |理论上, andor直接来自布尔逻辑(因此对两个布尔值进行运算以产生一个布尔值),而&| apply the boolean and/or to the individual bits of integers.将布尔值和/或应用于整数的各个位。 There are a lot lot of questions here on how the latter work exactly.这里有很多关于后者如何工作的问题。

Here are practical differences that potentially affect your results:以下是可能影响您的结果的实际差异:

  1. and and or short-circuiting, eg True or sys.exit(1) will not exit, because for a certain value of the first operand ( True or ... , False and ... ), the second one wouldn't change the result so does not need to be evaluated. andor短路,例如True or sys.exit(1)不会退出,因为对于第一个操作数的某个值( True or ...False and ... ),第二个不会改变结果因此不需要评估。 But |但是| and & don't short-circuit - True | sys.exit(1) and &不要短路 - True | sys.exit(1) True | sys.exit(1) throws you outta the REPL. True | sys.exit(1)会让你离开 REPL。
  2. & and | &| are regular operators and can be overloaded, while and and or are forged into the language (although the special method for coercion to boolean may have side effects).是常规运算符并且可以重载,while andor伪造到语言中(尽管强制转换为布尔值的特殊方法可能有副作用)。
    • This also applies to some other languages with operator overloading这也适用于其他一些带有运算符重载的语言
  3. and and or return the value of an operand instead of True or False . and and or返回操作数的值而不是TrueFalse This doesn't change the meaning of boolean expressions in conditions - 1 or True is 1 , but 1 is true, too.这不会改变条件中布尔表达式的含义 - 1 or True1 ,但1也是真的。 But it was once used to emulate a conditional operator ( cond ? true_val : false_val in C syntax, true_val if cond else false_val in Python).但它曾经被用来模拟条件运算符(在 C 语法中为cond ? true_val : false_val ,在 Python 中为true_val if cond else false_val )。 For & and |对于&| , the result type depends on how the operands overload the respective special methods ( True & False is False , 99 & 7 is 3 , for sets it's unions/intersection...). ,结果类型取决于操作数如何重载各自的特殊方法( True & FalseFalse99 & 73 ,对于集合,它是联合/交集......)。
    • This also applies to some other languages like Ruby, Perl and Javascript这也适用于其他一些语言,如 Ruby、Perl 和 Javascript

But even when eg a_boolean & another_boolean would work identically, the right solution is using and - simply because and and or are associated with boolean expression and condition while & and |但是,即使a_boolean & another_boolean工作方式相同,正确的解决方案是使用and - 仅仅因为andor与布尔表达式和条件 while &|相关联| stand for bit twiddling.代表有点玩弄。

Here's a further difference, which had me puzzled for a while just now: because & (and other bitwise operators) have a higher precedence than and (and other boolean operators) the following expressions evaluate to different values:这是另一个差异,刚才让我困惑了一段时间:因为& (和其他按位运算符)比and (和其他布尔运算符)具有更高的优先级and所以以下表达式计算为不同的值:

0 < 1 & 0 < 2

versus

0 < 1 and 0 < 2

To wit, the first yields False as it is equivalent to 0 < (1 & 0) < 2 , hence 0 < 0 < 2 , hence 0 < 0 and 0 < 2 .也就是说,第一个产生False因为它等价于0 < (1 & 0) < 2 ,因此0 < 0 < 2 ,因此0 < 0 and 0 < 2

If you are trying to do element-wise boolean operations in numpy , the answer is somewhat different.如果您尝试在numpy逐元素布尔运算,答案会有所不同。 You can use & and |您可以使用&| for element-wise boolean operations, but and and or will return value error.对于逐元素布尔运算,但是andor将返回值错误。

To be on the safe side, you can use the numpy logic functions .为了安全起见,您可以使用numpy 逻辑函数

np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False,  True], dtype=bool)

np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False,  True], dtype=bool)

The hint is in the name:提示在名称中:

  • Boolean operators are for performing logical operations (truth testing common in programming and formal logic)布尔运算符用于执行逻辑运算(编程和形式逻辑中常见的真值测试)
  • Bitwise operators are for "bit-twiddling" (low level manipulation of bits in byte and numeric data types)按位运算符用于“位旋转” (字节和数字数据类型中位的低级操作)

While it is possible and indeed sometimes desirable (typically for efficiency reasons) to perform logical operations with bitwise operators, you should generally avoid them for such purposes to prevent subtle bugs and unwanted side effects.虽然使用按位运算符执行逻辑运算是可能的,而且有时确实是可取的(通常是出于效率原因),但您通常应避免出于此类目的使用它们,以防止出现细微的错误和不需要的副作用。

If you need to manipulate bits, then the bitwise operators are purpose built.如果您需要操作位,那么按位运算符是专门构建的。 The fun book: Hackers Delight contains some cool and genuinely useful examples of what can be achieved with bit-twiddling.有趣的书: Hackers Delight包含一些很酷且真正有用的示例,说明可以通过 bit-twiddling 实现什么。

The general rule is to use the appropriate operator for the existing operands.一般规则是对现有操作数使用适当的运算符。 Use boolean (logical) operators with boolean operands, and bitwise operators with (wider) integral operands (note: False is equivalent to 0 , and True to 1 ).布尔(逻辑)运算符与布尔操作数一起使用,将位运算符与(更宽的)整数操作数一起使用(注意: False等效于0 ,而True等效于1 )。 The only "tricky" scenario is applying boolean operators to non boolean operands.唯一的“棘手”场景是将布尔运算符应用于非布尔操作数。
Let's take a simple example, as described in [SO]: Python - Differences between 'and' and '&' :让我们举一个简单的例子,如[SO]: Python - 'and' 和 '&' 之间的区别
5 & 7 vs. 5 and 7 . 5 & 75 and 7

For the bitwise and ( & ), things are pretty straightforward:对于按位( & ),事情非常简单:

 5 = 0b101 7 = 0b111 ----------------- 5 & 7 = 0b101 = 5

For the logical and , here's what [Python.Docs]: Boolean operations states ( emphasis is mine):对于逻辑and ,这里是[Python.Docs]: Boolean operations状态(重点是我的):

(Note that neither and nor or restrict the value and type they return to False and True , but rather return the last evaluated argument . (请注意,无论是也不限制值并键入他们返回虚假真实,而是返回最后一个变量

Example :示例

 >>> 5 and 7 7 >>> 7 and 5 5

Of course, the same applies for |当然,这同样适用于| vs. or ..

Boolean operation are logical operations.布尔运算是逻辑运算。

Bitwise operations are operations on binary bits.按位运算是对二进制位的运算。

Bitwise operations:按位运算:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

The operations:操作:

  • AND & : 1 if both bits are 1, otherwise 0 AND & : 如果两位都是 1,则为 1,否则为 0
  • OR || : 1 if either bit is 1, otherwise 0 : 如果任一位为 1,则为 1,否则为 0
  • XOR ^ : 1 if the bits are different, 0 if they're the same XOR ^ : 1 如果位不同,0 如果它们相同
  • NOT ~ ': Flip each bit NOT ~ ': 翻转每一位

Some of the uses of bitwise operations:按位运算的一些用途:

  1. Setting and Clearing Bits设置和清除位

Boolean operations:布尔运算:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 

Boolean 'and' vs. Bitwise '&':布尔“与”与按位“&”:

Pseudo-code/Python helped me understand the difference between these:伪代码/Python 帮助我理解了这些之间的区别:

def boolAnd(A, B):
    # boolean 'and' returns either A or B
    if A == False:
        return A
    else:
        return B

def bitwiseAnd(A , B):
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.)

    binA = binary(A)
    binB = binary(B)



    # perform boolean 'and' on each pair of binaries in (A, B)
    # then return the result:
    # equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])

    # assuming binA and binB are the same length
    result = []
    for i in range(len(binA)):
      compar = boolAnd(binA[i], binB[i]) 
      result.append(compar)

    # we want to return a string of 1s and 0s, not a list

    return ''.join(result)

Logical Operations逻辑运算

are usually used for conditional statements.通常用于条件语句。 For example:例如:

if a==2 and b>10:
    # Do something ...

It means if both conditions ( a==2 and b>10 ) are true at the same time then the conditional statement body can be executed.这意味着如果两个条件( a==2b>10 )同时为真,则可以执行条件语句体。

Bitwise Operations按位运算

are used for data manipulation and extraction.用于数据操作和提取。 For example, if you want to extract the four LSB (Least Significant Bits) of an integer, you can do this:例如,如果要提取整数的四个 LSB(最低有效位),可以执行以下操作:

p & 0xF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM