This question already has answers here:
How to do a bitwise NOR Gate in Python (editing python maths to work for me)
(2 answers)
Closed 9 years ago.
I'm trying to understand the code from an answer I received yesterday:
2nd: How to make a bitwise NOR gate
1st: How to do a bitwise NOR Gate in Python (editing python maths to work for me)
a=0b01100001
b=0b01100010
bin((a ^ 0b11111111) & (b ^ 0b11111111))
I now understand EVERYTHING except:
the & between the two values
and the ^ 11111111 ( I know that 0b is base 2)
Can someone please explain these?
How NOR works?
The expression x NOR y can be broken using AND, OR, and NOT:
x NOR y == NOT(x OR y) == NOT(x) AND NOT(y)
So, for your given values:
a=0b01100001
b=0b01100010
a NOR b would be NOT(a) AND NOT(b). Now think how would you do a NOT(a)? You just need to flip the bits. What is the way to flip the bits? An XOR(^). How?
0 ^ 1 == 1
1 ^ 1 == 0
So, taking the XOR of any bit with 1 will flip that bit. i.e. NOT(somebit) == a XOR somebit. So, in your case, just take an XOR of each bits in a and b with 1 will get you the NOT:
01100001
^ 11111111
------------
10011110
That is, we do an XOR with 11111111. Note the number of 1's is same as the number of bits in a.
Putting it together:
NOT(a) = a ^ 0b11111111
NOT(b) = b ^ 0b11111111
Now, that we got the NOTs of a and b, let's do an AND. So, what's the way to do an AND? Just do a bitwise &.
That's pretty simple:
NOT(a) AND NOT(b) == (a ^ 0b11111111) & (b ^ 0b11111111)
Related
I try to solve this problem
"Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array."
And one of the solution is below code using XOR
def find(arr1, arr2):
result=0
# Perform an XOR between the numbers in the arrays
for num in arr1+arr2:
result^=num
print result
return result
arr1 = [1,2,3,4,5,6,7]
arr2 = [3,7,2,1,4,6]
The result of the function is 5.
I know the basic principle of XOR. But I can't understand how the above code can find the result.
Some important concepts:
XOR of a number with itself is always 0
XOR of a number with 0 is always the number itself
The order of an XOR operation is inconsequential
With this, consider:
1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 3 ^ 7 ^ 2 ^ 1 ^ 4 ^ 6
→ (1 ^ 1) ^ (2 ^ 2) ^ (3 ^ 3) ^ (4 ^ 4) ^ (5) ^ (6 ^ 6) ^ (7 ^ 7)
→ 0 ^ 0 ^ 0 ^ 0 ^ 5 ^ 0 ^ 0
→ 5
And so, the odd one out remains.
You start with the result = 0
Then you keep XORing the result with all the elements of each array. The XOR flips all the nonzero bits of the number you currently have.
So when you encounter the same number twice, you have flipped the same set of bits twice - meaning that you are back at the state you started with.
Every number that appears in both lists ends up "canceling itself". The only number that is not canceled is the one that is missing from the second list.
It doesn't matter what each integer is - the bits will flip twice if the number appears twice, and once if the number appears once. It doesn't even matter if the number is missing in the first or the second array.
Need some help understanding python solutions of leetcode 371. "Sum of Two Integers". I found https://discuss.leetcode.com/topic/49900/python-solution/2 is the most voted python solution, but I am having problem understand it.
How to understand the usage of "% MASK" and why "MASK = 0x100000000"?
How to understand "~((a % MIN_INT) ^ MAX_INT)"?
When sum beyond MAX_INT, the functions yells negative value (for example getSum(2147483647,2) = -2147483647), isn't that incorrect?
class Solution(object):
def getSum(self, a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
MAX_INT = 0x7FFFFFFF
MIN_INT = 0x80000000
MASK = 0x100000000
while b:
a, b = (a ^ b) % MASK, ((a & b) << 1) % MASK
return a if a <= MAX_INT else ~((a % MIN_INT) ^ MAX_INT)
Let's disregard the MASK, MAX_INT and MIN_INT for a second.
Why does this black magic bitwise stuff work?
The reason why the calculation works is because (a ^ b) is "summing" the bits of a and b. Recall that bitwise xor is 1 when the bits differ, and 0 when the bits are the same. For example (where D is decimal and B is binary), 20D == 10100B, and 9D = 1001B:
10100
1001
-----
11101
and 11101B == 29D.
But, if you have a case with a carry, it doesn't work so well. For example, consider adding (bitwise xor) 20D and 20D.
10100
10100
-----
00000
Oops. 20 + 20 certainly doesn't equal 0. Enter the (a & b) << 1 term. This term represents the "carry" for each position. On the next iteration of the while loop, we add in the carry from the previous loop. So, if we go with the example we had before, we get:
# First iteration (a is 20, b is 20)
10100 ^ 10100 == 00000 # makes a 0
(10100 & 10100) << 1 == 101000 # makes b 40
# Second iteration:
000000 ^ 101000 == 101000 # Makes a 40
(000000 & 101000) << 1 == 0000000 # Makes b 0
Now b is 0, we are done, so return a. This algorithm works in general, not just for the specific cases I've outlined. Proof of correctness is left to the reader as an exercise ;)
What do the masks do?
All the masks are doing is ensuring that the value is an integer, because your code even has comments stating that a, b, and the return type are of type int. Thus, since the maximum possible int (32 bits) is 2147483647. So, if you add 2 to this value, like you did in your example, the int overflows and you get a negative value. You have to force this in Python, because it doesn't respect this int boundary that other strongly typed languages like Java and C++ have defined. Consider the following:
def get_sum(a, b):
while b:
a, b = (a ^ b), (a & b) << 1
return a
This is the version of getSum without the masks.
print get_sum(2147483647, 2)
outputs
2147483649
while
print Solution().getSum(2147483647, 2)
outputs
-2147483647
due to the overflow.
The moral of the story is the implementation is correct if you define the int type to only represent 32 bits.
Here is solution works in every case
cases
- -
- +
+ -
+ +
solution
python default int size is not 32bit, it is very large number, so to prevent overflow and stop running into infinite loop, we use 32bit mask to limit int size to 32bit (0xffffffff)
a,b=-1,-1
mask=0xffffffff
while (b & mask):
carry=a & b
a=a^b
b=carray <<1
print( (a&Mask) if b>0 else a)
For me, Matt's solution stuck in inifinite loop with inputs Solution().getSum(-1, 1)
So here is another (much slower) approach based on math:
import math
def getSum(a: int, b: int) -> int:
return int(math.log2(2**a * 2**b))
This question already has answers here:
>> operator in Python
(5 answers)
Closed 6 years ago.
Someone sent me this equation but I don't understand what it means.
result = ((~c1) >> 1) & 0x0FFFFFF
It has to do with converting the binary from a wiegand reader.
Reference
The >> operator in Python is a bitwise right-shift. If your number is 5, then its binary representation is 101. When right-shifted by 1, this becomes 10, or 2. It's basically dividing by 2 and rounding down if the result isn't exact.
Your example is bitwise-complementing c1, then right-shifting the result by 1 bit, then masking off all but the 24 low-order bits.
This statement means:
result = # Assign a variable
((~c1) # Invert all the bits of c1
>> 1) # Shift all the bits of ~c1 to the right
& 0x0FFFFFF; # Usually a mask, perform an & operator
The ~ operator does a two's complement.
Example:
m = 0b111
x = 0b11001
~x == 0b11010 # Performs Two's Complement
x >> 1#0b1100
m == 0b00111
x == 0b11001 # Here is the "and" operator. Only 1 and 1 will pass through
x & m #0b 1
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python - '>>' operator
There's some code that does this:
x = n - 1 >> 1
I don't know if I have to provide more syntax, but what does the >> mean? I've been searching all over, but can't find any explanation.
Its a shift right logical, it is a bitwise operation that tells the number to shift in bits by that amount. In this case you are shifting by 1, which is equivalent to dividing by 2.
If you do not understand bitwise operations, a simple conversion for you to remember would be this.
x >> n
is equivalent to
x // (2**n)
It is the bitwise shift-to-right operator.
It shifts the bits of the integer argument to the right by the number on the right-hand side of the expression:
>>> 8 >> 2
2
or illustrated in binary:
>>> bin(0b1000 >> 2)
'0b10'
Your code example is actually doubly confusing as it mixes arithmetic and bitwise operations. It should use the '//' integer division operation instead:
x = (n - 1) // 2
x >> y
is equivalent to
x.__rshift__(y)
which, as others have said, is meant to be a bitshift.
>> is the bitwise right shift operator. This operator move all bits in the first operand right by the second operand.
So: a >> b = a // 2**b
Example:
36 in binary is 0b100100
36 >> 1 is 0b10010 (last binary digit or "bit" is removed) which is 18
36 >> 2 is 0b1001 (2 bits removed) which is 9
Note that the operator goes after addition. So the code does n-1 first, then right shift it by 1 bit (i.e. divides by 2).
This question already has answers here:
Bitwise operation and usage
(17 answers)
Closed 10 months ago.
I came across the following code
numdigits = len(cardNumber)
oddeven = numdigits & 1
what exactly is going on here? I'm not sure what the "&" is doing.
Answer
The & symbol is a bitwise AND operator. Used with 1, it basically masks the value to extract the lowest bit, or in other words will tell you if the value is even or odd.
More Info on Python's & operator
For more information, see: http://wiki.python.org/moin/BitwiseOperators
Why it Works to check Odd vs. Even
EDIT: Adding this section since this answer is getting some love
The reason why ANDing a value with 1 tells if the value is odd or even may not be obvious at first.
The binary representation of a number is essentially the sum of a series of YES or NO for each power of 2 moving leftward starting in the rightmost digit with 1, 2, 4, 8, ...
There is only one way to represent any number in this way. E.g. the number 13 (base 10) can be written in binary as "1101" (or hexadecimal as 0xD, but that's beside the point). See here:
1 1 0 1
x x x x
8 4 2 1
= = = =
8 + 4 + 0 + 1 = 13
Notice that aside from the rightmost binary digit, all other 1 digits will add an even number (i.e. a multiple of 2) to the sum. So the only way to get an odd final sum is to add that odd 1 from the rightmost digit. So if we're curious if a number is odd or even, we can look at its binary representation and ignore everything except for the rightmost digit.
To do this, we use the bitwise AND operator. The value 1 in binary is expressed as 1:
0 0 0 1
x x x x
8 4 2 1
= = = =
0 + 0 + 0 + 1 = 1
ANDing a value with 1 like this will result in 1 if the value's rightmost bit is set, and 0 if it is not.
And because 0 is generally considered "false" in most languages, and non-zero values considered "true", we can simply say as a shortcut:
if (value & 1): do_something_with_odd_value()...
& is also used for taking the intersection of two Python sets:
set1 = {0,1,2,3}
set2 = {2,3,4,5}
print(set1 & set2)
>>>set([2, 3])
More generally, Python allows operator overloading, meaning you can write classes that re-interpret what the & operator does. This is how libraries such as Pandas and Numpy hijack &.
It's a bitwise operation, in this case assigning zero to oddeven if cardNumber has an even number of elements (and one otherwise).
As an example: suppose len(cardNumber) == 235. Then numdigits == 235, which is 0b11101011 in binary. Now 1 is '0b00000001' in binary, and when you "AND" them, bitwise, you'll get:
11101011
&
00000001
----------
= 00000001
Similarly, if numdigits were 234, you would get:
11101010
&
00000001
----------
= 00000000
So, it's basically a obfuscated way of checking if len(cardNumber) % 2. Probably written by someone with a C background, because it is not very pythonic - readability counts!
& is a bitwise and, which is an efficient way to do bit-level calculations. It is taking numdigits and and-ing it with 1, bit-by-bit.
It's a binary bitwise AND operator.