Reputation: 201
I have looked at Stack overflow answers for questions similar to mine, but I have not found answers that could address my question (here and here) or explain in a way that makes it clear to me. In trying to understand, I experimented as below:
def Even1(num): # I understand this and use it
if num % 2 == 0:
return num
def Even2(num):
return not (num & 1)
def Even3(num):
return not (num and 1)
filter(Even1, range(7)) ==> [2, 4, 6]
filter(Even2, range(7)) ==> [0, 2, 4, 6]
filter(Even3, range(7)) ==> [0]
1: not (4 & 1) = True
2: not (1 & 4) = True
3: not (4 & 2) = True
4: not (3 & 4) = True
5: not (4 & 3) = True
6: not (4 & 4) = False
7: not (3 & 1) = False
8: not (1 & 3) = False
9: not (3 & 2) = False
10: not (2 & 3) = False
11: not (3 & 3) = False
Based on #1 to #5 I thought any even number with any other number in a not (x & y)
arrangement evaluates to False (changed to True by not). I thought it had something to do with the fact that bin(x)
where x
is even ends in 0 and when odd ends in a 1. So maybe not
checks for the last bit. But #6 disproves that assumption. And also the order in which the numbers are presented
has no influence.
What does expression #6 have in common with expression #11 besides that each evalutes identical/equal numbers?
And based on #7 to #11 it looks like odd numbers in not (x & y)
where x and y both odd evaluate to True (changed to False by not). Would that be correct?
Lastly, Even2 and Even3: replace &
with and
. I understand that the first is bitwise, and the second logical, but what does that mean so that I end with the results.
Upvotes: 0
Views: 1484
Reputation: 4964
Bitwise operators are usually used to make logic operations bit by bit between the operands, using the corresponding index (same weight) bit from left to right.
You have to consider the binary representation of the operands
Example:
>>> bin(4 & 6)
'0b100'
>>> bin(4)
'0b100'
>>> bin(6)
'0b110'
>>> bin(4 & 6)
'0b100'
>>> bin(8)
'0b1000'
>>> bin(4 & 8)
'0b0'
>>> bin(4 | 8)
'0b1100'
>>>
Usually you don't mix these operands with the logical ones, you may, but that's uncommon.
Bitwise operators are very useful when thinking in binary or hexadecimal terms, and also for compact representation of a group of flags.
Example (faked):
Printer status in a single byte, where bit 0 is 1 for online, 0 for offline. Bit 1 is 1 for paper jam, 0 paper ok. Bit 3 is 1 for printer ready. You don't care about the other 5 bits.
Suppose
status = 0b10100101
See the last three bits:0b101
means online, paper ok, ready
Set it offline (force bit 0 to 0)
status = status & 0b11111110 # same as status = status & 254
Get rid of status you don't care
my_status = status & 0b00000111 # same as my_status = status & 7
Set flags to 1, but keep the ones you don't care with original values
status = status | 0b00000111
The 0b
numbers here are sometimes written with hexadecimal notation or even as decimal (in this case leaving them with a magical looking into the reading eyes, while binary and hexadecimal make explicit to the reader the bit values) numbers are known as a bit mask. It sets/unsets the wanted bits and preserves the rest, depending on mask value and bitwise operator (|
to set and &
to reset)
Now you see the rules for the logical operators you know are a bit different when dealing with True
, False
, 0
and empty/non-empty objects...
Upvotes: 0
Reputation: 816
In Python, 1 and 0's boolean equivalents are True
and False
, respectively. It doesn't stop there though any non-zero value in Python is considered True
When you do even & 1
you get 0 - because the right most bit of any even number is 0. When you execute return not 0
that's equivalent from a boolean standpoint to return not False
i.e. return True
When you do not (0 and 1)
that is equivalent to not (False and True)
i.e. not False
so return True
Let's go through some of your tests and see what we get:
not (4 & 1) = not 0100 & 0001 = not 0 = True
not (1 & 4) = not 0001 & 0100 = not 0 = True
not (4 & 2) = not 0100 & 0010 = not 0 = True
not (3 & 4) = not 0011 & 0100 = not 0 = True
not (4 & 3) = not 0100 & 0011 = not 0 = True
not (4 & 4) = not 1000 & 1000 = not 4 = False
not (3 & 1) = not 0011 & 0001 = not 1 = False
not (1 & 3) = not 0001 & 0011 = not 1 = False
not (2 & 3) = not 0010 & 0011 = not 2 = False
not (3 & 3) = not 0011 & 0011 = not 3 = False
Upvotes: 4