Performing Euclidean division a = b*q + r
, is like rounding the fraction a/b
to an integer quotient q
, and then compute the remainder r
.
The different results you see depends on the convention used for rounding the quotient...
If you round toward zero (truncate), you will get a symmetry around zero like in C:
truncate(7/3) = 2
7 = 3*2 + 1
truncate(-7/3) = -2
-7 = 3* -2 - 1
truncate(7/-3) = -2
7 = -3* -2 + 1
If you round toward negative infinity (floor), you will get a remainder like in Python:
floor(7/3) = 2
7 = 3*2 + 1
floor(-7/3) = -3
-7 = 3* -3 + 2
floor(7/-3) = -3
7 = -3* -3 - 2
If you round to nearest int (tie to whatever you want, to even, or away from zero) you'll get a centered modulo:
round(7/3) = 2
7 = 3*2 + 1
round(8/3) = 3
8 = 3*3 - 1
round(-7/3) = -2
-7 = 3* -2 - 1
round(7/-3) = -2
7 = -3* -2 + 1
You could try to implement your own modulo with rounding toward positive infinity (ceil), and you would invent a rather unconventional modulo, but it would still be kind of modulo...