Integer division in Python 3 - strange result with negative number [duplicate] - python

This question already has answers here:
Negative integer division surprising result
(5 answers)
Closed 7 years ago.
I am new to Python, and I am learning operators right now.
I understood that:
The / operator is used for floating point division and
// for integer division.
Example:
7//3 = 2
And 7//-3=-3. Why is the answer -3?
I am stuck here.

// is not integer division, but floor division:
7/-3 -> -2.33333...
7//-3 -> floor(7/-3) -> floor(-2.33333...) -> -3
PEP 238 on Changing the Division Operator:
The // operator will be available to request floor division unambiguously.
See also Why Python's Integer Division Floors (thanks to #eugene y) - Basically 7//-3 is -7//3, so you want to be able to write:
-7 = 3 * q + r
With q an integer (negative, positive or nul) and r an integer such that 0 <= r < 3. This only works if q = -3:
-7 = 3 * (-3) + 2

// is the operator for floor division.
This means that after the division is completed the "floor" function is applied (the value retrieved from the division is rounded down to the nearest integer regardless of whether the decimal part is greater or less than .5)
As for your example, be careful to note that for negative answers the floor division operator will still be rounding down (e.g. -5/2 --> -2.5 --> -3).

Related

Get a integer if there are no significant digits after decimal or get a float if there are significant digits after decimal in python

I was recently doing a question on geeks for geeks website where they required median of two sorted arrays, but they are asking answer to be a int if there are no digits after decimals or a float if there are digits after decimals. For example when giving median of even number arrays, we usually divide middle elements with two, so if middle elements are 2 and 4 then after division answer should be 3, or if elements are 3 and 4 answer should be 3.5. But if we use / operator in python it will return division of 2 and 4 as 3.0, and if we use // operator it will return division of 3 and 4 as 3 instead of 3.5. Is there any way to get around this instead of checking divisibility by 2.
You could try something like this potentially. Do the division as normal and then apply the following:
if int(x) == x: # will be true if x=5.0 but not if x = 5.5
x = int(x)

Difference between // and round() in Python

Is there a difference between using // (Integer Division) and the built-in round() function in Python? If I understand correctly, both will round to the nearest Integer but I'm unsure if the behaviour of both the function and the operator is exactly the same at all times. Can someone clarify? Can both of them be used "interchangeably"?
// is floor division, round rounds to nearest. // stays integer at all times, round using / converts to float before rounding back, which might not work at all for large enough ints, and can lose precision for smaller (but still large) ints.
If you need floor division of ints, always use // (you can do ceiling division too, with -(-num // div)). It's always correct, where round (and math.floor) might not be (for ints exceeding about 53 bits). round is more configurable (you can round off to a specified number of decimal places, including negative decimal places to round off to the left of the decimal point), but you want to avoid converting to float at all whenever you can.
>>> 5 // 2
2
>>> round(5 / 2)
2
>>> round(5 / 2, 1)
2.5
>>>
The round function gives you more control over the precision of rounding. The // operator provides the floor (rounds down) of dividing the two.
Consider also:
>>> round(20 / 3)
7
>>> 20 // 3
6
>>>
// and round() are two different things.
// is divide, then floor
round() is a function to make a float number shorter.
>>> 10 // 3 # 10 divide to 3, then floor
3
>>> round(10 / 3, 2) # 10 divide to 3, take 2 number after the dot
3.33

The math calculations behind using (%, //) in python by applying (Decimal(), signed numbers )?

I was trying to understand the math behind calculations using / and // and % operators by doing some trials and found the results are similar to calculator only when using Decimal() but without it the results kinda confusing, i tried to add comments #No Ideato my code to mark the points i don't understand,for example:
in this trial for % operator by applying signed and unsigned number the results and with and without Decimal() the results are :
>>> 9%5 #This result will be the reminder
4
>>> (-9)%5 #No Idea
1
>>> Decimal(9)% Decimal(5) #This result will be the reminder
Decimal('4')
>>> Decimal(-9)% Decimal(5) #The result will be the signed reminder
Decimal('-4')
in this trial for // operator and using signed and unsigned number with and without Decimal() the results are :
>>> 9//5 #int result
1
>>> -9//5 #No Idea
-2
>>> Decimal(9)/Decimal(5) #Same result as using calculator
Decimal('1.8')
>>> Decimal(-9)//Decimal(5) #No Idea
Decimal('-1')
Please consider that this question is not a duplicate and i have done some research to get an answer but i found some answered questions that explain only about // operator using only positive signed numbers and doesn't include information about negative signed numbers or using the Decimal() and doesn't have answer about % operator.
so,It will be helpful if someone knows why the results are different and how they are calculated.
Explanation for the behaviour of integers
From python documentation:
Division of integers yields a float, while floor division of integers
results in an integer; the result is that of mathematical division
with the ‘floor’ function applied to the result.
Therefore, an integer division (//) of negative negative and positive number works as follows:
-9 // 5 == floor(-9 / 5) == floor(-1.8) == -2
The modulo operator is the remainder of the integer division, i.e. x % y = x - x // y * y. In your example:
-9 % 5 == -9 - (-9 // 5 * 5) == (-9) - (-2 * 5) == (-9) - (-10) == 1
The documentation also says:
The modulo operator always yields a result with the same sign as its
second operand (or zero); the absolute value of the result is strictly
smaller than the absolute value of the second operand.
But that comes naturally from the formula above, e.g.:
9 % -5 == 9 - (9 // (-5) * (-5)) == 9 - (-2 * (-5)) == 9 - 10 == -1
decimal.Decimal is different
The documentation explains the difference well:
There are some small differences between arithmetic on Decimal objects
and arithmetic on integers and floats. When the remainder operator %
is applied to Decimal objects, the sign of the result is the sign of
the dividend rather than the sign of the divisor:
>>> (-7) % 4
1
>>> Decimal(-7) % Decimal(4)
Decimal('-3')
The integer division operator // behaves analogously, returning the
integer part of the true quotient (truncating towards zero) rather
than its floor, so as to preserve the usual identity x == (x // y) * y
+ x % y:
>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')
As I understand the question, the OP is asking about the different behavior between Python integers and Decimals. I don't think there is any good reason for it. Both choices are possible, but it is a bit confusing for the user that they differ.
Let's call the numerator n, the denominator d and split the result in the interger result i and the remainder r. This means that
n // d = i
n % d = r
For the operations to make sense, we need
i * d + r == n
For n = -9 and d = 5 we see that this is uphold for both i = -1, r = -4 and for i = -2, r = 1 as can be seen by
(i = -1, r = -4) => -1 * 5 + -4 == -9
(i = -2, r = 1) => -2 * 5 + 1 == -9
Now, in Python integer division is defined as always truncate towards minus infinity (down) and the Decimal implementation has chosen to round towards zero. That means that positive values are truncated/rounded down, whereas negative values are rounded up.
Rounding towards zero is the choice made also made in the C language. However, my personal opinion is that the Python choice is much more sane, specifically coming from a hardware background. And given that this is the choice made in Python, I think it is strange (and bad) that Decimal has chosen to do as in the C language.

Modulo for negative dividends in Python [duplicate]

This question already has answers here:
How does the modulo (%) operator work on negative numbers in Python?
(12 answers)
Closed last month.
Been looking through other answers and I still don't understand the modulo for negative numbers in python
For example the answer by df
x == (x/y)*y + (x%y)
so it makes sense that (-2)%5 = -2 - (-2/5)*5 = 3
Doesn't this (-2 - (-2/5)*5) =0 or am I just crazy?
Modulus operation with negatives values - weird thing?
Same with this
negative numbers modulo in python
Where did he get -2 from?
Lastly if the sign is dependent on the dividend why don't negative dividends have the same output as their positive counterparts?
For instance the output of
print([8%5,-8%5,4%5,-4%5])
is
[3, 2, 4, 1]
In Python, modulo is calculated according to two rules:
(a // b) * b + (a % b) == a, and
a % b has the same sign as b.
Combine this with the fact that integer division rounds down (towards −∞), and the resulting behavior is explained.
If you do -8 // 5, you get -1.6 rounded down, which is -2. Multiply that by 5 and you get -10; 2 is the number that you'd have to add to that to get -8. Therefore, -8 % 5 is 2.
In Python, a // b is defined as floor(a/b), as opposed to most other languages where integer division is defined as trunc(a/b). There is a corresponding difference in the interpretation of a % b = a - (a // b) * b.
The reason for this is that Python's definition of the % operator (and divmod) is generally more useful than that of other languages. For example:
def time_of_day(seconds_since_epoch):
minutes, seconds = divmod(seconds_since_epoch, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return '%02d:%02d:%02d' % (hours, minutes, seconds)
With this function, time_of_day(12345) returns '03:25:45', as you would expect.
But what time is it 12345 seconds before the epoch? With Python's definition of divmod, time_of_day(-12345) correctly returns '20:34:15'.
What if we redefine divmod to use the C definition of / and %?
def divmod(a, b):
q = int(a / b) # I'm using 3.x
r = a - b * q
return (q, r)
Now, time_of_day(-12345) returns '-3:-25:-45', which isn't a valid time of day. If the standard Python divmod function were implemented this way, you'd have to write special-case code to handle negative inputs. But with floor-style division, like my first example, it Just Works.
The rationale behind this is really the mathematical definition of least residue. Python respects this definition, whereas in most other programming language the modulus operator is really more like a 'reaminder after division' operator. To compute the least residue of -5 % 11, simply add 11 to -5 until you obtain a positive integer in the range [0,10], and the result is 6.
When you divide ints (-2/5)*5 does not evaluate to -2, as it would in the algebra you're used to. Try breaking it down into two steps, first evaluating the part in the parentheses.
(-2/5) * 5 = (-1) * 5
(-1) * 5 = -5
The reason for step 1 is that you're doing int division, which in python 2.x returns the equivalent of the float division result rounded down to the nearest integer.
In python 3 and higher, 2/5 will return a float, see PEP 238.
Check out this BetterExplained article and look # David's comment (No. 6) to get what the others are talking about.
Since we're working w/ integers, we do int division which, in Python, floors the answer as opposed to C. For more on this read Guido's article.
As for your question:
>>> 8 % 5 #B'coz (5*1) + *3* = 8
3
>>> -8 % 5 #B'coz (5*-2) + *2* = -8
2
Hope that helped. It confused me in the beginning too (it still does)! :)
Say -a % b needs to be computed. for ex.
r= 11 % 10
find the next number after 11 that is perfectly divisible by 10 i.e on dividing that next number after 11 gives the remainder 0.
In the above case its 20 which on dividing by 10 gives 0.
Hence, 20-11 = 9 is the number that needs to be added to 11.
The concept if 60 marbles needs to be equally divided among 8 people, actually what you get after dividing 60/8 is 7.5 since you can'nt halve the marbles, the next value after 60 that is perfectly divisible by 8 is 64. Hence 4 more marbles needs to be added to the lot so that everybody share the same joy of marbles.
This is how Python does it when negatives numbers are divided using modulus operator.

Python and Floats

I have this code :
N = 10
for i in range(1,N):
P[i,i] = (i/N) + pow((1-i/N),2)
But my division operations are getting rounded down to the nearest integer.
How can I instruct Python to do floating-point division?
You are doing integer division. Try something like this:
N = 10
for i in range(1,N):
P[i,i] = (float(i)/N) + pow((1-float(i)/N),2)
Add this line to the top of your script:
from __future__ import division
This will allow division of integers to give floats with the usual division operator /. If you also need to perform integer division, you can use //:
>>> 9/10
0.90000000000000002
>>> 9//10
0
This will be the standard behavior in Python 3.
In Python 2.x, division between two integers is the mathematical division, but floored. Since you're dividing two integers, one being equal or smaller than the other, you get 1s and 0s.
To have the correct behavior, use floats:
N = 10.0
for i in range(1, int(N) ):
P[i,i] = (i/N) + pow((1-i/N),2)
Note that Python 3.x does mathematical division with two integers

Categories