When I compare two numbers at python, even though they are exactly the same, the difference between these two numbers is not zero, but something really small (<10^(-16)).
e.g.
if A == B:
print('We are the same')
Nothing happens.
But:
if A - B < 10^(-16):
print(A-B)
It prints the difference.
Where is the problem?
in Python, the ^ operator execute an exclusive or, so 10^(-16) means 10 XOR (-16), which correctly returns -6 (which is lower than A-B).
If you wanted to execute an exponentiation, you have to write 10**(-16), and your check is now working as expected.
This means that your code should be:
if A - B < 10**(-16):
print(A-B)
# OUTPUT: 0
Related
I'd expect bin(~0b111000) to return the value 0b000111 because to my understanding the NOT operation would return the opposite bit as output.
I keep reading that "~x: Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1" so I don't exactly know where my logic breaks down.
Why does it show -(x + 1) instead of just literally flipping all bits?
It is flipping all the bits!
You seem to think of 0b111000 as a 6bit value. That is not the case. All integers in python3 have (at least conceptually) infinitely many bits. So imagine 0b111000 to be shorthand for 0b[...]00000111000.
Now, flipping all the bits results in 0b[...]11111000111. Notice how in this case the [...] stands for infinitely many ones, so mathematically this gets interesting. And we simply cannot print infinitely many ones, so there is no way to directly print this number.
However, since this is 2s complement, this simply means: The number which, if we add 0b111001 to it, becomes 0. And that is why you see -0b111001.
For two numbers x and y that are base b, does this work for subtracting them? The numbers are given in string format and 2 <= b <= 10.
def n2b(n, b): # function to convert number n from base 10 to base b
if n == 0:
return 0
d = []
while n:
d.append(int(n % b))
n /= b
return ''.join(map(str,d[::-1]))
x = int(x,b) # convert to integers in base 10
y = int(y,b)
z = x - y
z = n2b(z,b) # convert back to base b, still in integer form
You have some confusion about how integers work in python. As the comments above say: python always stores integers in binary form and only converts them to a base when you print them. Depending on how you get x and y and how you need to give back z the code needs to be different
Situation 1: x, y and z are all integers
In this case you only need to do
z = x - y
And you're done.
Situation 2: x, y and z are all strings
In this case you first need to convert the strings into integers with the right base. I think that's your case, since you already deal with int(x, b) which is correct to transform a string into an integer (e.g. int("11", 2) gives 3 (integer represented in base 10). I would advice you to reform your code into something like this:
x_int = int(x, b)
y_int = int(y, b)
z_str = n2b(x_int - y_int, b)
In your code x is first a string and then an integer, which is bad practice. So e.g. use x_int instead of x.
Now it comes down to if your n2b function is correct. It looks good from the distance, although you're not handling signs and bases bigger than 10. There is a broadly accepted convert integer to base b answer so you might take this to be sure.
This is exactly the problem I just ran into in the google foobar challenge (which I suspect is the same source of ops problem). Granted its years later and op has no use for my answer but someone else might.
The issue
The function op used looked a lot like a copy and paste of this provided by the accepted answer but slightly modified (although I didn't look to closely).
I used the same function and quickly realized that I needed my output to be a string. Op appears to have realized the same thing based on the return statement at the end of the function.
This is why most of the test cases passed. Op did almost everything right.
See, the function begins with
if n==0:
return 0
One of the test cases in the foobar challenge uses 0 as the input. Its an easy line to miss but a very important one.
Solution
When I was presented this problem, I thought about the possible outlier cases. 0 was my first idea (which turned out to be right). I ran the program in vscode and would ya look at that - it failed.
This let me see the error message (in my case it was a list rather than int but op would have received a similar error).
The solution is simply changing return 0 to return '0' (a string rather than int)
I wasn't super excited to write out this answer since it feels a bit like cheating but its such a small detail that can be so infuriating to deal with. It doesn't solve the challenge that foobar gives you, just tells you how to get past a speed bump along the way.
Good luck infiltrating commander lambda's castle and hopefully this helps.
I am trying to solve a problem, using python code, which requires me to add two integers without the use of '+' or '-' operators. I have the following code which works perfectly for two positive numbers:
def getSum(self, a, b):
while (a & b):
x = a & b
y = a ^ b
a = x << 1
b = y
return a ^ b
This piece of code works perfectly if the input is two positive integers or two negative integers but it fails when one number is positive and other is negative. It goes into an infinite loop. Any idea as to why this might be happening?
EDIT: Here is the link discussing the code fix for this.
Python 3 has arbitrary-precision integers ("bignums"). This means that anytime x is negative, x << 1 will make x a negative number with twice the magnitude. Zeros shifting in from the right will just push the number larger and larger.
In two's complement, positive numbers have a 0 in the highest bit and negative numbers have a 1 in the highest bit. That means that, when only one of a and b is negative, the top bits of a and b will differ. Therefore, x will be positive (1 & 0 = 0) and y will be negative (1 ^ 0 = 1). Thus the new a will be positive (x<<1) and the new b will be negative (y).
Now: arbitrary-precision negative integers actually have an infinite number of leading 1 bits, at least mathematicallly. So a is a larger and larger positive number, expanding by 2 each iteration. b keeps getting more and more leading 1 bits added to be able to carry out the bitwise & and ^ with a. Thus whatever bits of a are turned on line up with one of the added 1 bits of b, so a & b is always true, so the loop runs forever.
I faced the same problem.
More precise: you get infinity loop only when one number positive, another negative AND positive >= abs(negative).
As #cvx said it works so because of extra carry bit - another languages ignore overflows, but python adds this additional 1 to number and it become more and more and b never become zero.
So the solution is to use mask: lets ignore this additional bit:
def getSum(a: int, b: int) -> int:
mask = 0xffffffff
while b&mask > 0:
carry = a & b
cur_sum = a ^ b
a = cur_sum
b = carry << 1
return a&mask if b>0 else a
Also the last line is important! As python adds such 1 to a also, and python thinks about it like a negative value. We should skip those bits and get only last part of the a as positive number.
More information here: https://leetcode.com/problems/sum-of-two-integers/discuss/489210/Read-this-if-you-want-to-learn-about-masks
I'm guessing that this is a homework question, so I don't want to just give you a function that works --- you'll learn more by struggling with it.
The issue stems from the way that negative integers are stored. For illustration purposes, let's pretend that you're dealing with 4-bit signed integers (instead of 32-bit signed integers, or whatever). The number +1 is 0001. The number -1 is 1111. You should be able to sit down with a pen and paper and manually run your function using these two numbers. The answer, of course, should be 0000, but I think you'll discover what's going wrong with your code by working this simplified case with a pen and paper.
a += b != a & 1
I came across this statement in a code, but I'm not sure what the final part (!= a & 1) of the code does. What does that do?
First you have to consult the language specification to realize what the order of operations are here. With parentheses put out this will be:
a += (b != (a & 1))
The a & 1 is bitwise and (making it 1 if a is odd and 0 otherwise), then the result of that is compared to b and the result of that which is boolean will be added to a. Now of course for the latest to be meaningful a need to be of a type that can support that (integer types does that for example, by taking True as having value of 1 and False having value of 0).
To sum it up, if b==0 it will increase a if a is even and if b==1 it will increase a if a is odd. Otherwise if b is neither 0 nor 1 it will increase a.
I noticed that some of the comments didn't notice the precedence order, and even in python they may sometimes be confusing (especially if you've already been confused by those from C). As a rule of thumb I'd recommend that you explicitely place parentheses around sub expressions if you're in the tiniest bit of doubt - or even break it down in separate statemenst. Normally the compiler will make the best of it anyway.
In coding a primality tester, I came across an interesting thought. When you want to do something if the result of an operation turns out to be 0, which is the better ('pythonic') way of tackling it?
# option A - comparison
if a % b == 0:
print('a is divisible by b')
# option B - is operator
if a % b is 0:
print('a is divisible by b')
# option C - boolean not
if not a % b:
print('a is divisible by b')
PEP 8 says that comparisons to singletons like None should be done with the is operator. It also says that checking for empty sequences should use not, and not to compare boolean values with == or is. However, it doesn't mention anything about checking for a 0 as a result.
So which option should I use?
Testing against 0 is (imo) best done by testing against 0. This also indicates that there might be other values than just 0 and 1.
If the called function really only returns 0 on success and 1 on fail to say Yes/No, Success/Failure, True/False, etc., then I think the function is the problem and should (if applicable) be fixed to return True and False instead.
just personal : I prefer the not a % b way because it seems to be highly readable. But now, to lower the confusion level in the code, I will use the == 0, as it express what you expect to test exactly in a more accurate way. It's the "care for debug" approach.
0 isn't guaranteed to be a singleton so don't use is to test against it: currently C Python re-uses small integers so there is probably only one int with the value 0 plus a long if you're still on Python 2.x, and any number of float zeroes not to mention False which all compare equal to 0. Some earlier versions of Python, before it got a separate bool type used a different int zero for the result of comparisons.
Use either == (which would be my preference) or just the not, whichever you prefer.
A and C are both valid and very pythonic.
B is not, because
0 semantically is not a singleton (it is in cPython, but that is an implementation detail).
It will not work with float a or b.
It is actually possible that this will not work in some other implementation of Python.