Integer division & modulo operation with negative operands in Python
Asked Answered
G

4

10

Questions arise when I type in these expressions to Python 3.3.0

-10 // 3  # -4
-10 % 3   #  2
10 // -3  # -4
10 % -3   # -2
-10 // -3 #  3

It appears as though it takes the approximate floating point (-3.33)? and rounds down either way in integer division but in the modulo operation it does something totally different. It seems like it returns the remainder +/-1 and only switches the sign depending on where the negative operand is. I am utterly confused, even after looking over other answers on this site! I hope someone can clearly explain this too me! The book says hint: recall this magic formula a = (a//b)(b)+(a%b) but that doesn't seem to clear the water for me at all.

-Thanks in advance!

Edit: Those are just my personal assessments of what happens (above), I know, I'm completely off!

Gabriellagabrielle answered 15/1, 2013 at 22:36 Comment(1)
possible duplicate of negative numbers in pythonEagle
T
7

The integer division there is just taking the floor of the number obtained at the end.

10/3  -> floor(3.33)  ->  3
-10/3 -> floor(-3.33) -> -4

(Why it floors)


The modulo operation on the other hand is following the mathematical definition.

Thankful answered 15/1, 2013 at 22:43 Comment(0)
C
6
  • Magic formula: a = (a // b) * b + (a % b)
  • a: -10
  • b: 3
  • a // b: -4
  • a % b: 2

    Substitute in magic formula: -10 = -4 * 3 + 2 = -12 + 2 = -10

  • a: 10

  • b: -3
  • a // b: -4
  • a % b: -2

    In magic formula: 10 = -4 * -3 - 2 = 12 - 2 = 10

So the magic formula seems to be correct.

If you define a // b as floor(a / b) (which it is), a % b should be a - floor(a / b) * b. Let's see:

  • a: -10
  • b: 3
  • a % b = a - floor(a / b) * b = -10 - floor(-3.33) * 3 = -10 + 4 * 3 = 2

 

The fact that a // b is always floored is pretty easy to remember (please read Cthulhu's first link, it's an explanation by the creator of Python). For negative a in a % b.. try to imagine a table of numbers that starts at 0 and has b columns:

b = 3:

0  1  2
3  4  5
6  7  8
9 10 11
...

If a is the number in a cell, a % b would be the column number:

a         a % b
_______________
0  1  2   0 1 2
3  4  5   0 1 2
6  7  8   0 1 2
9 10 11   0 1 2

Now extend the table back in the negatives:

   a          a % b
 __________________
-12 -11 -10   0 1 2
 -9  -8  -7   0 1 2
 -6  -5  -4   0 1 2
 -3  -2  -1   0 1 2
  0   1   2   0 1 2
  3   4   5   0 1 2
  6   7   8   0 1 2
  9  10  11   0 1 2

-10 % 3 would be 2. Negative a in a % b would come up in these sorts of context. a % b with negative b doesn't come up much.

Connubial answered 15/1, 2013 at 22:45 Comment(4)
Thanks! @Pavel do you have an experience when this would come into play? What would you recommend I try and remember for when these expressions arise? Always plug them into the magic formula?Gabriellagabrielle
okay, thanks for extending that for me! Unfortunately it didn't seem to clear it up for me :( I haven't had a math class since my second year in college so I apologize for my stupidity. It is unwise to just add one or subtract one to whatever the normal remainder would be? (depending of course on where the negative operand is in the equation)Gabriellagabrielle
Quite unwise, e.g.: 50 % 13 = 11, -50 % 13 = 2 (you can just flip the sign of 11 or 2 in case of a -13 though). You have to mentally split the number line in b-sized blocks. Then a % b is the position of a in a block. Look at graphs on wikipedia. Ours is the floored division.Connubial
okay, thanks for the heads up. I'll be looking into this more forsureGabriellagabrielle
S
2

A simple rule: for a % b = c, if c is not zero, then should have the same sign as b.

And apply the magic formula:

10 % -3 = -2 => 10 // -3 = (10 - (-2)) / (-3) = -4

-10 % 3 = 2 => -10 // 3 = (-10 - 2) / 3 = -4

-10 % -3 = -1 => -10 // -3 = (-10 - (-1)) / (-3) = 3

Sagacity answered 15/1, 2013 at 23:6 Comment(2)
Thanks! So whenever addressing these problems always plug them in to the formula? This is still such a puzzling to meGabriellagabrielle
@tlands_: Yes, See:divmod(x, y) == (x//y, x%y)Sagacity
B
1

OK, so I did some digging and I think that the problem isn't Python, but rather the Modulo function. I'm basing this answer off of Link

10 % 3 Uses the highest multiple of 3 that is LESS THAN 10. In this case, 9. 10 - 9 = 1

-10 % 3 does the same thing. It's still looking for a multiple of 3 that is LESS THAN -10. In this case, -12. (-10) - (-12) = 2

Brace answered 15/1, 2013 at 22:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.