Fundamentos
Operadores aritméticos y precedencia en Python: /, //, % y **
Aprende +, -, *, /, //, % y ** en Python, el orden en que se resuelven las cuentas y los errores de precedencia que engañan incluso a quien ya programa.
Por Prof. Rodrigo Faustino · Actualizado el · 12 min de lectura
Métricas de este artículo
- Palabras
- 2261
- Caracteres
- 12.862
- Tiempo de lectura
- ~12 min
Python tiene siete operadores aritméticos: +, -, *, /, //, % y **. Los cuatro primeros son los de siempre. Los otros tres merecen atención: / devuelve la división con decimales, // devuelve solo la parte entera de la división, % devuelve el resto, y ** eleva a una potencia. Cuando una cuenta mezcla varios operadores, Python resuelve primero las potencias, después las multiplicaciones y divisiones, de izquierda a derecha, y por último las sumas y restas. Los paréntesis cambian ese orden.
Parece poco, y es poco, pero casi todo programa que hace alguna cuenta depende de acertar estas reglas. Un promedio calculado con la precedencia equivocada no da error, da un número plausible y equivocado, y eso es mucho peor que un mensaje rojo. Este texto muestra cada operador con lo que responde, el orden de las cuentas y los errores que suelen aparecer, incluso en código de gente con bastante camino recorrido.
El problema: la cuenta de la cabeza y la cuenta del computador
Cuando lees 8 + 6 / 2, la cabeza lo resuelve en el orden correcto sin pedir permiso: seis dividido entre dos es tres, ocho más tres es once. La matemática de la escuela enseñó esa prioridad, y Python sigue la misma. El problema aparece cuando la intención era otra. Si la idea era el promedio de 8 y 6, la cuenta correcta es (8 + 6) / 2, que da 7. Sin los paréntesis Python calcula 8 + 3, que da 11, y no se queja de nada.
Ese es el tipo de error que ningún mensaje avisa. Para el computador, a + b / 2 es una expresión perfectamente válida. Quien sabe si representa el promedio eres tú. Por eso conocer el orden de resolución no es un detalle de examen: es la diferencia entre un programa que hace la cuenta que imaginaste y uno que hace otra.
La IA que recuerda tu vida y vive en tu ordenador
- Memoria a largo plazo con la fuente de cada respuesta
- Funciona sin conexión: tus datos se quedan en tu PC
- Lee PDF, diapositivas, fotos y grabaciones de reuniones
Plan Esencial gratis para siempre
Los siete operadores
| Operador | Nombre | Ejemplo | Resultado |
|---|---|---|---|
+ | suma | 7 + 2 | 9 |
- | resta | 7 - 2 | 5 |
* | multiplicación | 7 * 2 | 14 |
/ | división | 7 / 2 | 3.5 |
// | división entera | 7 // 2 | 3 |
% | resto de la división | 7 % 2 | 1 |
** | potencia | 7 ** 2 | 49 |
print(7 + 2, 7 - 2, 7 * 2, 7 / 2, 7 // 2, 7 % 2, 7 ** 2)
print(17 / 5, 17 // 5, 17 % 5)
print(divmod(17, 5))
print(10 / 2, type(10 / 2), 10 // 2, type(10 // 2))
print(7.0 // 2, 7 // 2.0, 7.5 % 2)La primera línea muestra los siete resultados de la tabla. La segunda y la tercera reaparecen justo debajo. La cuarta confirma una regla del artículo anterior: 10 / 2 vale 5.0, un float, incluso cuando la cuenta sale exacta, y 10 // 2 vale 5, un int. La última muestra que // y % también funcionan con decimales, pero el resultado de // sigue siendo un valor "redondeado hacia abajo", ahora en forma de float (3.0).
Tres divisiones, tres preguntas
Dividir 17 entre 5 tiene tres respuestas, y cada operador da una de ellas.
El // responde "cuántos grupos completos de 5 caben en 17": tres. El % responde "qué sobra después de esos grupos": dos. El / responde "cuánto da la división exacta": 3,4. Las tres respuestas se relacionan por una identidad que sirve de comprobación: 5 * 3 + 2 vuelve a dar 17. La función divmod(17, 5) devuelve el cociente y el resto de una vez, como el par (3, 2).
Cuál usar depende de la pregunta. Para repartir 47 figuritas entre 6 amigos, el // dice cuántas recibe cada uno (7) y el % dice cuántas sobran (5). Para calcular un promedio, el / es el correcto, porque la respuesta tiene decimales.
Números negativos: el redondeo es hacia abajo
El // no "corta" la parte decimal: redondea al menor entero. Con números positivos eso es lo mismo. Con negativos, no:
print(-7 // 2, -7 % 2)
print(7 // -2, 7 % -2)
print(-7 // 2, int(-7 / 2))
print(-7 % 3, 7 % 3)La salida muestra -4 1, -4 -1, -4 -3 y 2 1. Fíjate en la tercera línea: -7 // 2 da -4, e int(-7 / 2) da -3, porque el int() corta la parte decimal en lugar de redondear hacia abajo. Las dos escrituras parecen la misma operación y dan respuestas distintas. En Python, el resto % tiene el mismo signo que el divisor, y eso es lo que hace que -7 % 3 valga 2 y no -1. Esa elección mantiene siempre verdadera la identidad divisor * cociente + resto = dividendo.
El resto sirve para más de lo que parece
El % es uno de los operadores más útiles de la programación, y casi todos los usos giran en torno a ciclos. El resto de la división entre 2 dice si un número es par (n % 2 == 0). El resto entre 24 hace que un reloj dé la vuelta: después de las 22 horas, más 5 horas, son las 3 de la madrugada, y (22 + 5) % 24 vale 3. El resto entre 7 hace lo mismo con los días de la semana. Y (0 - 1) % 7 vale 6: retroceder un día desde el domingo lleva al sábado, sin necesidad de ninguna cuenta especial para el caso del negativo.
Potencia y raíz
El ** eleva un número a una potencia: 2 ** 10 vale 1024. El exponente puede ser negativo (2 ** -1 vale 0.5) o fraccionario (16 ** 0.5 vale 4.0, la raíz cuadrada). Para la raíz cuadrada, el módulo math tiene una función propia, math.sqrt(16), que también devuelve 4.0. Existen además math.floor(), que redondea hacia abajo, y math.ceil(), que redondea hacia arriba.
import math
print(math.sqrt(16), math.floor(3.7), math.ceil(3.2), math.floor(-3.2))
print(abs(-5), abs(-2.5), pow(2, 10), min(3, 1, 2), max(3, 1, 2))
print(round(3.14159, 2), round(2.5), round(3.5), round(7.0))Las funciones abs(), pow(), min(), max() y round() ya vienen con Python y no necesitan import. Una sorpresa en el round(): round(2.5) da 2 y round(3.5) da 4. Cuando el número está exactamente en el medio, Python redondea al entero par más cercano. Quien viene de otro lenguaje, o recuerda la regla de la escuela, espera 3 en los dos casos.
Del programa al semestre planificado
- Plan de enseñanza y calendario montados solos
- Diario de clases listo para pegar en el SIGA
- Diapositivas y listas de ejercicios con solucionario
Versión Community gratis · Windows
El orden en que se resuelven las cuentas
Cuando una expresión tiene más de un operador, Python sigue un orden fijo, del que "se pega más fuerte" al que se pega menos.
Primero viene la potencia, después el signo negativo, después las multiplicaciones y divisiones (*, /, // y %, todas en el mismo nivel), y por último la suma y la resta. Los operadores del mismo nivel se resuelven de izquierda a derecha. Por eso 10 - 2 - 3 vale 5 (primero 10 - 2, después 8 - 3), y 8 / 2 * 4 vale 16.0, y no 1.0: Python divide primero y multiplica después.
print(2 + 3 * 4)
print((2 + 3) * 4)
print(2 + 3 * 4 ** 2)
print(-2 ** 2, (-2) ** 2)
print(2 ** 3 ** 2, (2 ** 3) ** 2)
print(10 - 2 - 3, 10 - (2 - 3))
print(8 / 2 * 4, 8 / (2 * 4))
print(10 % 4 * 2, 10 % (4 * 2))La potencia es la excepción a la regla de izquierda a derecha: agrupa por la derecha. Entonces 2 ** 3 ** 2 calcula primero 3 ** 2, que da 9, y después 2 ** 9, que da 512. Y -2 ** 2 vale -4, no 4, porque la potencia se resuelve antes que el signo, que actúa solo sobre el resultado. En los dos casos, quien escribe la cuenta casi siempre quería otra cosa. En caso de duda, usa paréntesis: no cuestan nada, dejan la intención visible para quien lea después y nunca están equivocados.

Asignación aumentada
Cuando la cuenta actualiza la propia variable, Python ofrece una forma corta. En lugar de x = x + 5, se escribe x += 5. Hay una versión para cada operador.
x = 10
x += 5
print(x)
x -= 3
print(x)
x *= 2
print(x)
x //= 5
print(x)
x **= 2
print(x)
x %= 7
print(x)
x /= 2
print(x)La salida es 15, 12, 24, 4, 16, 2 y 1.0. Fíjate en el último valor: el /= transformó el entero en float, porque la división con / siempre devuelve decimal. Python no tiene x++ ni x--, que existen en C y en Java. Quien intenta escribir x++ recibe SyntaxError: invalid syntax, y la forma correcta es x += 1.
Qué cambia en la ESP32
Los operadores se comportan igual en MicroPython y en el Python del computador, con una diferencia que ya apareció en la serie: el float de la ESP32 tiene 32 bits. Las cuentas con decimales, por lo tanto, pueden dar resultados distintos.
print(100 * 1.1)
print(0.1 * 3)
print(7 / 3)
print(2 ** 100)En el simulador, esas líneas muestran 110.0, 0.3, 2.3333332 y 1267650600228229401496703205376. En el Python del computador, las tres primeras muestran 110.00000000000001, 0.30000000000000004 y 2.3333333333333335. Los enteros, como el de la cuarta línea, no tienen ese problema: la precisión es exacta y solo está limitada por la memoria. El artículo sobre variables y tipos tiene la tabla completa de esa diferencia.
Los mensajes de error de la división por cero también cambian. Para 10 / 0, 10 // 0 y 10 % 0, MicroPython muestra siempre ZeroDivisionError: divide by zero. El Python del computador distingue: division by zero, integer division or modulo by zero, integer modulo by zero y, con decimales, float division by zero. La causa es la misma: el divisor valía cero. Cuando el programa reciba el divisor de afuera (de un input(), de un sensor, del tamaño de una lista), conviene proteger la cuenta con una decisión, tema del próximo módulo.
Ejemplo trabajado: segundos en horas, minutos y segundos
Un uso clásico de // y % juntos es convertir un total de segundos en horas, minutos y segundos. La idea se aplica a cualquier conversión de unidad en la que una magnitud mayor se divide en menores.
total = 3725
horas = total // 3600
resto = total % 3600
minutos = resto // 60
segundos = resto % 60
print(horas, minutos, segundos)
print(f"{horas:02d}:{minutos:02d}:{segundos:02d}")El // con 3600 dice cuántas horas completas hay en 3725 segundos: una. El % con 3600 guarda lo que sobró: 125 segundos. Con ese resto, la misma pareja se repite: // 60 da 2 minutos y % 60 da 5 segundos. El :02d dentro de la f-string completa con cero a la izquierda, y la salida queda 01:02:05. Para comprobar, vuelve por el camino inverso: 1 * 3600 + 2 * 60 + 5 da 3725.
Errores de precedencia y de operador que comete hasta quien programa hace años
Los escenarios de abajo no son solo de principiante. Aparecen en el código de gente con experiencia, en general por apuro o por un hábito traído de otro lenguaje.
El promedio sin paréntesis
Alguien escribe el promedio de dos notas con apuro: media = nota1 + nota2 / 2. Con las notas 7 y 8, el programa muestra 11.0, un promedio mayor que las dos notas, lo que ya debería encender la alerta. Con los paréntesis, (nota1 + nota2) / 2 muestra 7.5. El error sobrevive porque la cuenta corre sin ningún mensaje, y muchas veces solo se nota cuando alguien comprueba el resultado con la calculadora.
El ^ que no es potencia
En varios lenguajes y en calculadoras, el acento circunflejo representa la potencia. En Python, 2 ^ 3 no es ocho. Es un operador bit a bit llamado "o exclusivo", y el resultado es 1. El programa sigue corriendo y el número está mal. La potencia en Python es siempre **. Los otros operadores bit a bit existen (&, |, << y >>) y son importantes para quien trabaja con hardware, pero no hacen cuentas de matemática.
El resto con signo distinto
Quien trabaja con C, Java o JavaScript se acostumbra a que -7 % 3 valga -1. En Python, vale 2. Si un programa se traduce de uno de esos lenguajes sin atención a esto, las cuentas de ciclo (días de la semana, posición en un vector circular) pasan a dar valores distintos solo cuando el número es negativo, lo que hace que el defecto sea difícil de encontrar: el programa pasa todas las pruebas con números positivos.
El int() en lugar del //
Otro caso de lenguaje de origen. Quien quiere "dividir y quedarse con la parte entera" escribe int(a / b). Con positivos, el resultado es el mismo que a // b. Con negativos, no: ya vimos que int(-7 / 2) vale -3 y -7 // 2 vale -4. Antes de cambiar uno por el otro, decide qué comportamiento pide el problema.
El x++ y la multiplicación implícita
Dos errores de sintaxis que se repiten. El primero es el x++, que termina en SyntaxError: invalid syntax. El segundo es escribir 2(3 + 4) como en la matemática, esperando que el número pegado a los paréntesis multiplique. Python lo entiende como una llamada a función, y el resultado es TypeError: 'int' object isn't callable. La multiplicación siempre pide el *: 2 * (3 + 4).
Ejercicio: el vuelto en billetes
Un cajero necesita devolver R$ 289 en billetes de 50, 20, 10, 5 y 2 reales, usando la menor cantidad de billetes. Escribe el programa que muestra cuántos billetes de cada valor. Piensa primero en la idea: cuántos billetes de 50 caben en 289, qué sobra, y la misma pregunta para el siguiente billete.
valor = 289
n50 = valor // 50
valor = valor % 50
n20 = valor // 20
valor = valor % 20
n10 = valor // 10
valor = valor % 10
n5 = valor // 5
valor = valor % 5
n2 = valor // 2
valor = valor % 2
print("50:", n50, "20:", n20, "10:", n10, "5:", n5, "2:", n2, "sobra:", valor)La salida es 50: 5 20: 1 10: 1 5: 1 2: 2 sobra: 0. Cada par // y % repite el razonamiento de los segundos: el cociente es el número de billetes y el resto es lo que sobra para el siguiente billete. Prueba con otros valores. El sobra muestra lo que no se pudo pagar con esos billetes, y con valor = 1 ves el resultado sobra: 1. Después, intenta reescribir el programa usando divmod() en cada paso.
Preguntas frecuentes
¿Por qué el / devuelve 5.0 y no 5?
Porque la división con / siempre devuelve float, incluso cuando las dos partes son enteras y la cuenta es exacta. Así el tipo del resultado no depende de los valores. Si necesitas un entero, usa //.
¿Cuál es la diferencia entre ** y pow()?
Para dos argumentos, ninguna: 2 ** 10 y pow(2, 10) dan 1024. El operador es más corto y entra en la tabla de precedencia; la función es útil para pasarla como argumento a otras funciones.
¿Python tiene ++ y --?
No. Usa += 1 y -= 1. El ++ existe en la sintaxis de C y de Java, y en Python se leería como dos signos de más seguidos, sin sentido.
¿Necesito memorizar la tabla de precedencia?
Solo el orden de los cuatro niveles, que es el de la matemática. Para todo lo que no sea obvio, los paréntesis resuelven. La tabla completa de Python tiene más niveles (comparaciones, lógicos y otros), y aparecen en los próximos artículos, un módulo cada vez.
Para continuar
La ruta Lógica con Python tiene desafíos que usan cada operador. El Multiplicación simple es el calentamiento, el División entera y el Resto de la división ejercitan // y %, y el Promedio ponderado exige la precedencia con paréntesis.
El próximo tema de la serie es la conversión de tipos: int(), float(), str() y los errores que aparecen cuando el texto no tiene la forma de un número. Antes de él, conviene releer el artículo sobre entrada y salida, porque las cuentas de este texto cobran sentido cuando los valores vienen del input().