简体   繁体   中英

Don't understand why if (5 & 2): is False

This is a pretty trivial question that I haven't been able to find the answer to.

Here is the problem.

#1

if 3 & 2:
    print('True')
else:
    print('False')
#1 result = True

#2

if 5 & 2:
    print('True')
else:
    print('False')
#2 result = False

I think the reason is Bitwise operators, but I don't understand this situation.

Any clarification would be much appreciated.

In Python, a single ampersand & is a binary AND operator. Meaning that the operation is executed on each bit of the given numbers.

If we will look at the values of 2 and 3 in binary:

DEC:  2 &  3 =  2
BIN: 10 & 11 = 10

While 5 and 2:

DEC:   5 &   2 =   0
BIN: 101 & 010 = 000

Side note:

If you meant to use logical AND, which checks that both values are not False (not 0 for numbers), then you should use the keyword and

There are two things going on here:

  • The bitwise operation itself.

    • The output of the & is a number that has 1 for every bit where the corresponding bit is 1 in both operands, 0 elsewhere. In this case (in binary) for 5 & 2 you have the operands 101 and 010 , hence binary output 000 or in decimal: 0 , whereas for 3 & 2 you have the operands 11 and 10 , hence binary output 10 or in decimal: 2 .
  • The action of if when the condition is an integer:

    • Where the condition is an integer, if the value is non-zero then it will be treated as a true value, whereas 0 will be treated as a false value. Therefore in the 5 & 2 case, the 0 is treated as false, and the else block will be executed, whereas in the 3 & 2 case, the 2 is treated as true, and the if block is executed.

Putting these together, and recalling that 2 is an exact power of 2 (in this case 2 to the power 1), what this essentially is doing is testing whether, if you write the other number in binary, the 2s digit is set (ie is equal to 1) or not. This coding pattern is commonly used where you have a number which represents a bit field and you want to test if a particular bit is set. For example, the flags argument of the os.open function (its second argument) is a bit field. You can test whether a particular bit of interest is set in a flags value which you might send to that function:

import os
print(os.O_RDWR)  # 2 - in binary 10
print(os.O_TRUNC)  # 512 - in binary 1000000000
flags = os.O_RDWR | os.O_TRUNC  # does bitwise OR to set the flags
print(flags)  # 514 - in binary this is 1000000010

if flags & os.O_RDWR:
    print("O_RDWR is set")  # this print is executed because the 2s digit is set

& is a bitwise and operator thus it will per perform AND on each bit and if one of the bit is one it give output as true.

If you observe 5 and 2 in their bit form 5 is complement of 2 (5 is 101 and 2 is 010). Therefore as per AND logic table AA' is always equal to 0. That's why your answer is false

if 3 & 2:
    print('True')
else:
    print('False')

&,|, ^ are used as bitwise operators in python. Other languages like C or C++ will use &&, || as comparison operators, which can lead to some confusion in python.

So in the above code, 3 & 2 would evaluate it in the binary form of these base 10 numbers. So it would become 11 & 10 which would be evaluated as 10 ie 2 . In python 0 will be regarded as False in a conditional statement, whereas 2 would become True so your code would print True.

You can read about operators and Truth Values in python here : https://docs.python.org/3/library/stdtypes.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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