¿Cómo funciona el operador de módulo (%) en números negativos en Python?
¿Exactamente cómo %
funciona el operador en Python, particularmente cuando se trata de números negativos?
Por ejemplo, ¿por qué se -5 % 4
evalúa como 3
, en lugar de, digamos, -1
?
A diferencia de C o C++, el operador de módulo de Python ( %
) siempre devuelve un número que tiene el mismo signo que el denominador (divisor). Tu expresión produce 3 porque
(-5) / 4 = -1,25 --> piso(-1,25) = -2
(-5) % 4 = (-2 × 4 + 3) % 4 = 3.
Se elige sobre el comportamiento C porque un resultado no negativo suele ser más útil. Un ejemplo es calcular los días de la semana. Si hoy es martes (día #2), ¿cuál es el día de la semana N días antes? En Python podemos calcular con
return (2 - N) % 7
pero en C, si N ≥ 3, obtenemos un número negativo que no es válido y debemos arreglarlo manualmente sumando 7:
int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;
(Consulte http://en.wikipedia.org/wiki/Modulo_operator para saber cómo se determina el signo del resultado para diferentes idiomas).
Aquí hay una explicación de Guido van Rossum:
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
Esencialmente, es así que a/b = q con resto r preserva las relaciones b*q + r = a y 0 <= r < b.
En Python , el operador de módulo funciona así.
>>> mod = n - math.floor(n/base) * base
entonces el resultado es (para tu caso):
mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3
mientras que otros lenguajes como C, JAVA y JavaScript utilizan truncamiento en lugar de piso.
>>> mod = n - int(n/base) * base
lo que resulta en:
mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1
Si necesita más información sobre el redondeo en Python, lea esto .
Otras respuestas, especialmente la seleccionada, claramente han respondido bastante bien a esta pregunta. Pero me gustaría presentar un enfoque gráfico que también podría ser más fácil de entender, junto con el código Python para realizar el módulo matemático normal en Python.
Módulo Python para principiantes
La función de módulo es una función direccional que describe cuánto tenemos que movernos más o menos después de los saltos matemáticos que damos durante la división sobre nuestro eje X de números infinitos. Así que digamos que estabas haciendo7%3
Entonces, en dirección hacia adelante, su respuesta sería +1, pero en dirección hacia atrás:
tu respuesta sería -2. Ambos son correctos matemáticamente .
De manera similar, también tendrías 2 módulos para números negativos. Por ejemplo: -7%3
, puede resultar en -1 o +2 como se muestra -
dirección hacia adelante
dirección hacia atrás
En matemáticas elegimos saltos hacia adentro, es decir, hacia adelante para un número positivo y hacia atrás para números negativos.
Pero en Python, tenemos una dirección directa para todas las operaciones de módulo positivo. De ahí tu confusión...
>>> -5 % 4
3
>>> 5 % 4
1
Aquí está el código de Python para el módulo de tipo de salto hacia adentro en Python:
def newMod(a,b):
res = a%b
return res if not res else res-b if a<0 else res
que daría -
>>> newMod(-5,4)
-1
>>> newMod(5,4)
1
Mucha gente se opondría al método del salto hacia adentro, pero mi opinión personal es que ¡¡este es mejor!!