+ 17

# In python, why expression (-4%3) results in 2?

19 odpowiedzi

+ 17

mesenger It's similar to floor division rule -- modulo gives the distance to the closest *lower* divisible.

+ 35

Although unintuitive, it's kind of logical, because:
3%3 == 0
2%3 == 2
1%3 == 1
0%3 == 0
-1%3 == 2
-2%3 == 1
-3%3 == 0
-4%3 == 2
-5%3 == 1
-6%3 == 0
...

+ 7

I've heard this summarized as "Python always takes the sign of the denominator", problematic for an older answer of mine:
https://www.sololearn.com/Discuss/74000/why-4-10-4-4-10-6
...I wrote "the remainder must be less than the divisor AND positive", which is true for that example...
...but i think it's better phrased as:
"Python takes the remainder that is between the divisor and 0"
The docs say "the absolute value of the result is strictly smaller than the absolute value of the second operand".
To "prove" my theory, using the formula in the other post (total - q*divisor = remainder):
-4 % 3 ... -4 - ?(3) = an integer in the interval [+0 to +2]
-4 - (-2)(3) = -4 + 6 = 2
4 % -3 ... 4 - ?(-3) = an integer ... [-2 to -0] * note on floats+signed 0
4 - (-2)(-3) = 4 - 6 = -2
-4 % -3 ... -4 - ?(-3) = an integer ... [-2 to -0]
-4 - (-1)(-3) = -4 + 3 = -1
4 % 3 ... (the obvious case)
4 - (1)(3) = 4 - 3 = 1
Each answer was checked against Python 3.6.5
* [meta] An anomaly, 4 % -4 = +0. 4.0 % -4.0 = -0.0

+ 5

-4/3 = -2 + 2/3

+ 5

In case of modulo and floordivision, are there real life use cases for doing this with negative values? I haven't encountered a case myself yet.

+ 4

HonFu
If it's Wednesday, 10:00 hours now, what were the day and time 90 hours ago?
Answer: Saturday, 16:00 hours.
(10 - 90) // 24 = (-80) // 24 = -4
(4 days before Wed is Sat--which, by the way, is also modular arithmetic 😉)
(10 - 90) % 24 = (-80) % 24 = 16

+ 4

Kirk Schafer Succinctly put! Though the word "between" is a little vague, as it's a half-closed interval (remainder never equals the divisor).
For anyone interested, I'm quoting a little more from the docs:
"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.
The floor division and modulo operators are connected by the following identity: x == (x//y)*y + (x%y)."
I guess their motivation is to make this standard relation between the dividend, divisor, quotient and remainder work (while defining "//" as floor division).
Full text: https://docs.python.org/3/reference/expressions.html

+ 3

This is probably off-topic, but Kirk Schafer, what is -0.0 in the context of Python, and how do we know 4.0 % (-4.0) is -0.0?

+ 2

Kishalaya Saha I tried to fix the ambiguity--reducing the limit by 1 in favor of the closed interval because I thought "oh...the half-open interval seems better-suited to floating point modulus":
print(3.999999 % 2)
1.999998999...
Thanks for the extra doc context :)

+ 2

I see there are a lot o way to understand this probem.
-4%3, well my way is think in number nx3 at wich nx3-4>=0. In this case 2x3-4>0. So the difference , 2, is the result of -4%3.

+ 1

Well, OK thank you. But what reasoning python uses to support this sequence?

+ 1

anyone who got a link to tutorials i can learn this part coz have tried to figure out but am getting nothing

+ 1

expression (-4%3) results in 2
The concept is this, % is the modulo or remainder operator. It is just like saying that what is the remainder when -4 is divided by 3. So here, since the number, -4 is less than the modulo, 3 you were to leave the answer to be the number but here again, the number is less than 0. You must make sure the number is greater than zero by adding the modulo, 3 to the number, -4 until is becomes positive. -4 + 3= -1 +3 = 2 mod3 = 2. because the 2 is less the modulo, 3

0

Because, the negation operator which convert binary bits
So, the ~ 4 convert the 5.
And modulo operator returns the reminder so, 5%3 is 2

0

[Reposting*]
Guido's explanation, reasoning + maths.
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
If you work out the invariants with respect to zero, it appears to be my prior conclusion:
negative b : positive b
b < r <= 0 : 0 <= r < b
His example: To calculate time of day as a negative offset from some 0 (like UNIX epoch or years BC<-0->AD)
It leverages time counting backwards from time=0, but days counting forward every 86400 seconds back.
[-2 ][-1 ][0 ][1 ] Day#
^-172800 ^-86400 ^0 ^86400 Time, seconds
With Guido's method, divmod(-100000, 86400) = (-2, 72800)
This means +72800 seconds from DAY -2's left edge, a straightforward answer.
* This code is an attempt to envision the above more elegantly, but I don't have a proper analysis of additional +/- cases.
I think it's accurate for the above only, so please be gentle with my fiddly experiment.
https://code.sololearn.com/cz3A1pIL2npH/?ref=app

0

just remember while taking modulus(%) of two number and if the first number is negative then keep on adding the second number in first number till the first number becomes positive
eg: -4%3
-4+3=-1
-1+3=2
and now just take modulus
2%3=2 :)

0

-4%3 = 3-(4%3)
= 3-1
= 2
we can do modulus of any negative number like this
example -8%5 = 5 - (8%5)
= 5 - 3
= 2

- 1

1

- 1

Forget about logic, binary and atc. The core problem is: What is the math definition of this operation?
a%d=r, from math point of view we have:
a=q*d+r, and in addition 0<=r<=|d|
so
-4=q*3+r
we know that r>=0 so if we want to keep the minus result, the 3*q<0
and we can even say more: 3*q<-4
if 3*q<-4 then q<-4/3
I forgot to say that q must be an integer, so the nearest integer which can fullfill q value is -2
q=-2
now we have
-4 = -2 * 3 + r
-4 + 6 = r
r = 2
the end.
I took a q=-2, but the condition was q<-4/3, that means we have a lot of other values like -5, -66 etc, which are good.
But we have to take this one value for q, which allows r become a number from 0 to |d|.