Fundamentos
Operadores aritméticos e precedência em Python: /, //, % e **
Aprenda a usar +, -, *, /, //, % e ** em Python, a ordem em que as contas são resolvidas e os erros de precedência que enganam até quem já programa.
Por Prof. Rodrigo Faustino · Atualizado em · 12 min de leitura
O Python tem sete operadores aritméticos: +, -, *, /, //, % e **. Os quatro primeiros são os de sempre. Os outros três merecem atenção: / devolve a divisão com decimais, // devolve só a parte inteira da divisão, % devolve o resto, e ** eleva à potência. Quando uma conta mistura vários operadores, o Python resolve primeiro as potências, depois as multiplicações e divisões, da esquerda para a direita, e por último as somas e subtrações. Parênteses mudam essa ordem.
Parece pouco, e é pouco, mas quase todo programa que faz alguma conta depende de acertar essas regras. Uma média calculada com a precedência errada não dá erro, dá um número plausível e errado, e isso é muito pior do que uma mensagem vermelha. Este texto mostra cada operador com o que ele responde, a ordem das contas e os erros que costumam aparecer, inclusive em código de gente com bastante tempo de estrada.
O problema: a conta da cabeça e a conta do computador
Quando você lê 8 + 6 / 2, a cabeça resolve na ordem certa sem pedir licença: seis dividido por dois é três, oito mais três é onze. A matemática da escola ensinou essa prioridade, e o Python segue a mesma. O problema aparece quando a intenção era outra. Se a ideia era a média de 8 e 6, a conta correta é (8 + 6) / 2, que dá 7. Sem os parênteses o Python calcula 8 + 3, que dá 11, e não reclama de nada.
Esse é o tipo de erro que nenhuma mensagem avisa. Para o computador, a + b / 2 é uma expressão perfeitamente válida. Quem sabe se ela representa a média é você. Por isso conhecer a ordem de resolução não é detalhe de prova: é a diferença entre um programa que faz a conta que você imaginou e um que faz outra.
A IA que lembra da sua vida e mora no seu computador
- Memória de longo prazo com a fonte de cada resposta
- Funciona offline: seus dados ficam no seu PC
- Lê PDFs, slides, fotos e gravações de reunião
Plano Essencial grátis para sempre
Os sete operadores
| Operador | Nome | Exemplo | Resultado |
|---|---|---|---|
+ | soma | 7 + 2 | 9 |
- | subtração | 7 - 2 | 5 |
* | multiplicação | 7 * 2 | 14 |
/ | divisão | 7 / 2 | 3.5 |
// | divisão inteira | 7 // 2 | 3 |
% | resto da divisão | 7 % 2 | 1 |
** | potência | 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)A primeira linha mostra os sete resultados da tabela. A segunda e a terceira reaparecem logo abaixo. A quarta confirma uma regra do artigo anterior: 10 / 2 vale 5.0, um float, mesmo quando a conta fecha redonda, e 10 // 2 vale 5, um int. A última mostra que // e % também funcionam com decimais, mas o resultado de // continua sendo um valor "arredondado para baixo", agora na forma de float (3.0).
Três divisões, três perguntas
Dividir 17 por 5 tem três respostas, e cada operador dá uma delas.
O // responde "quantos grupos completos de 5 cabem em 17": três. O % responde "o que sobra depois desses grupos": dois. O / responde "quanto dá a divisão exata": 3,4. As três respostas se relacionam por uma identidade que serve de conferência: 5 * 3 + 2 volta a dar 17. A função divmod(17, 5) devolve o quociente e o resto de uma vez, como o par (3, 2).
Quando usar cada um depende da pergunta. Para dividir 47 figurinhas entre 6 amigos, o // diz quantas cada um recebe (7) e o % diz quantas sobram (5). Para calcular uma média, o / é o certo, porque a resposta tem decimais.
Números negativos: o arredondamento é para baixo
O // não "corta" a parte decimal: ele arredonda para o menor inteiro. Com números positivos isso é a mesma coisa. Com negativos, não:
print(-7 // 2, -7 % 2)
print(7 // -2, 7 % -2)
print(-7 // 2, int(-7 / 2))
print(-7 % 3, 7 % 3)A saída mostra -4 1, -4 -1, -4 -3 e 2 1. Repare na terceira linha: -7 // 2 dá -4, e int(-7 / 2) dá -3, porque o int() corta a parte decimal em vez de arredondar para baixo. As duas escritas parecem a mesma operação e dão respostas diferentes. Em Python, o resto % tem o mesmo sinal do divisor, e é isso que faz -7 % 3 valer 2 e não -1. Essa escolha mantém a identidade divisor * quociente + resto = dividendo sempre verdadeira.
O resto serve para mais do que parece
O % é um dos operadores mais úteis da programação, e quase todos os usos giram em torno de ciclos. O resto da divisão por 2 diz se um número é par (n % 2 == 0). O resto por 24 faz um relógio dar a volta: depois das 22 horas, mais 5 horas, são 3 da manhã, e (22 + 5) % 24 vale 3. O resto por 7 faz o mesmo com os dias da semana. E (0 - 1) % 7 vale 6: voltar um dia a partir do domingo leva ao sábado, sem precisar de nenhuma conta especial para o caso do negativo.
Potência e raiz
O ** eleva um número a uma potência: 2 ** 10 vale 1024. O expoente pode ser negativo (2 ** -1 vale 0.5) ou fracionário (16 ** 0.5 vale 4.0, a raiz quadrada). Para a raiz quadrada, o módulo math tem uma função própria, math.sqrt(16), que também devolve 4.0. Existem ainda math.floor(), que arredonda para baixo, e math.ceil(), que arredonda para cima.
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))As funções abs(), pow(), min(), max() e round() já vêm com o Python e não precisam de import. Uma surpresa no round(): round(2.5) dá 2 e round(3.5) dá 4. Quando o número está exatamente no meio, o Python arredonda para o inteiro par mais próximo. Quem vem de outra linguagem, ou lembra da regra da escola, espera 3 nos dois casos.
Da ementa ao semestre planejado
- Plano de ensino e calendário montados sozinhos
- Diário de aulas pronto para colar no SIGA
- Slides e listas de exercícios com gabarito
Versão Community grátis · Windows
A ordem em que as contas são resolvidas
Quando uma expressão tem mais de um operador, o Python segue uma ordem fixa, de quem "gruda mais forte" para quem gruda menos.
Primeiro vem a potência, depois o sinal negativo, depois as multiplicações e divisões (*, /, // e %, todas no mesmo nível), e por último a soma e a subtração. Operadores do mesmo nível são resolvidos da esquerda para a direita. Por isso 10 - 2 - 3 vale 5 (primeiro 10 - 2, depois 8 - 3), e 8 / 2 * 4 vale 16.0, e não 1.0: o Python divide primeiro e multiplica depois.
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))A potência é a exceção à regra da esquerda para a direita: ela agrupa pela direita. Então 2 ** 3 ** 2 calcula 3 ** 2 primeiro, que dá 9, e depois 2 ** 9, que dá 512. E -2 ** 2 vale -4, não 4, porque a potência é resolvida antes do sinal, que age só sobre o resultado. Nos dois casos, quem escreve a conta quase sempre queria outra coisa. Na dúvida, use parênteses: eles não custam nada, deixam a intenção visível para quem ler depois e nunca estão errados.

Atribuição aumentada
Quando a conta atualiza a própria variável, o Python oferece uma forma curta. Em vez de x = x + 5, escreve-se x += 5. Há uma versão 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)A saída é 15, 12, 24, 4, 16, 2 e 1.0. Repare no último valor: o /= transformou o inteiro em float, porque a divisão com / sempre devolve decimal. O Python não tem x++ nem x--, que existem em C e em Java. Quem tenta escrever x++ recebe SyntaxError: invalid syntax, e a forma correta é x += 1.
O que muda na ESP32
Os operadores se comportam igual no MicroPython e no Python do computador, com uma diferença que já apareceu na série: o float da ESP32 tem 32 bits. Contas com decimais, portanto, podem dar resultados diferentes.
print(100 * 1.1)
print(0.1 * 3)
print(7 / 3)
print(2 ** 100)No simulador, essas linhas mostram 110.0, 0.3, 2.3333332 e 1267650600228229401496703205376. No Python do computador, as três primeiras mostram 110.00000000000001, 0.30000000000000004 e 2.3333333333333335. Os inteiros, como o da quarta linha, não têm esse problema: a precisão é exata e só é limitada pela memória. O artigo sobre variáveis e tipos tem a tabela completa dessa diferença.
As mensagens de erro da divisão por zero também mudam. Para 10 / 0, 10 // 0 e 10 % 0, o MicroPython mostra sempre ZeroDivisionError: divide by zero. O Python do computador diferencia: division by zero, integer division or modulo by zero, integer modulo by zero e, com decimais, float division by zero. A causa é a mesma: o divisor valia zero. Quando o programa receber o divisor de fora (de um input(), de um sensor, do tamanho de uma lista), vale proteger a conta com uma decisão, assunto do próximo módulo.
Exemplo trabalhado: segundos em horas, minutos e segundos
Um uso clássico de // e % juntos é converter um total de segundos em horas, minutos e segundos. A ideia se aplica a qualquer conversão de unidade em que uma grandeza maior se divide em 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}")O // com 3600 diz quantas horas completas existem em 3725 segundos: uma. O % com 3600 guarda o que sobrou: 125 segundos. Com esse resto, a mesma dupla se repete: // 60 dá 2 minutos e % 60 dá 5 segundos. O :02d dentro da f-string completa com zero à esquerda, e a saída vira 01:02:05. Para conferir, volte pelo caminho inverso: 1 * 3600 + 2 * 60 + 5 dá 3725.
Erros de precedência e de operador que até quem programa há anos comete
Os cenários abaixo não são só de iniciante. Aparecem no código de gente experiente, em geral por pressa ou por hábito vindo de outra linguagem.
A média sem parênteses
Alguém escreve a média de duas notas na pressa: media = nota1 + nota2 / 2. Com as notas 7 e 8, o programa mostra 11.0, uma média maior do que as duas notas, o que já deveria acender o alerta. Com os parênteses, (nota1 + nota2) / 2 mostra 7.5. O erro sobrevive porque a conta roda sem nenhuma mensagem, e muitas vezes só é percebido quando alguém confere o resultado com a calculadora.
O ^ que não é potência
Em várias linguagens e em calculadoras, o acento circunflexo representa a potência. No Python, 2 ^ 3 não é oito. É um operador bit a bit chamado "ou exclusivo", e o resultado é 1. O programa continua rodando e o número está errado. A potência em Python é sempre **. Os outros operadores bit a bit existem (&, |, << e >>) e são importantes para quem mexe com hardware, mas não fazem conta de matemática.
O resto com sinal diferente
Quem trabalha com C, Java ou JavaScript acostuma-se a -7 % 3 valendo -1. No Python, vale 2. Se um programa for traduzido de uma dessas linguagens sem atenção a isso, as contas de ciclo (dias da semana, posição num vetor circular) passam a dar valores diferentes só quando o número é negativo, o que torna o defeito difícil de achar: o programa passa em todos os testes com números positivos.
O int() no lugar do //
Outro caso de linguagem de origem. Quem quer "dividir e ficar com a parte inteira" escreve int(a / b). Com positivos, o resultado é o mesmo de a // b. Com negativos, não: já vimos que int(-7 / 2) vale -3 e -7 // 2 vale -4. Antes de trocar um pelo outro, decida qual comportamento o problema pede.
O x++ e a multiplicação implícita
Dois erros de sintaxe que se repetem. O primeiro é o x++, que termina em SyntaxError: invalid syntax. O segundo é escrever 2(3 + 4) como na matemática, esperando que o número encostado nos parênteses multiplique. O Python entende isso como uma chamada de função, e o resultado é TypeError: 'int' object isn't callable. A multiplicação sempre pede o *: 2 * (3 + 4).
Exercício: o troco em notas
Um caixa precisa devolver R$ 289 em notas de 50, 20, 10, 5 e 2 reais, usando o menor número de notas. Escreva o programa que mostra quantas notas de cada valor. Pense primeiro na ideia: quantas notas de 50 cabem em 289, o que sobra, e a mesma pergunta para a próxima nota.
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)A saída é 50: 5 20: 1 10: 1 5: 1 2: 2 sobra: 0. Cada par // e % repete o raciocínio dos segundos: o quociente é o número de notas e o resto é o que sobra para a próxima nota. Teste com outros valores. O sobra mostra o que não deu para pagar com essas notas, e com valor = 1 você vê o resultado sobra: 1. Depois, tente reescrever o programa usando divmod() em cada passo.
Perguntas frequentes
Por que o / devolve 5.0 e não 5?
Porque a divisão com / sempre devolve float, mesmo quando as duas partes são inteiras e a conta é exata. Assim o tipo do resultado não depende dos valores. Se você precisa de um inteiro, use //.
Qual a diferença entre ** e pow()?
Para dois argumentos, nenhuma: 2 ** 10 e pow(2, 10) dão 1024. O operador é mais curto e entra na tabela de precedência; a função é útil para passar como argumento para outras funções.
O Python tem ++ e --?
Não. Use += 1 e -= 1. O ++ existe na sintaxe de C e de Java, e no Python seria lido como dois sinais de mais seguidos, sem sentido.
Preciso decorar a tabela de precedência?
Só a ordem dos quatro níveis, que é a da matemática. Para tudo o que não for óbvio, parênteses resolvem. A tabela completa do Python tem mais níveis (comparações, lógicos e outros), e eles aparecem nos próximos artigos, um módulo de cada vez.
Para continuar
A trilha Lógica com Python tem desafios que usam cada operador. O Multiplicação simples é o aquecimento, o Divisão inteira e o Resto da divisão exercitam // e %, e o Média ponderada cobra a precedência com parênteses.
O próximo assunto da série é a conversão de tipos: int(), float(), str() e os erros que aparecem quando o texto não tem a forma de um número. Antes dele, vale reler o artigo sobre entrada e saída, porque as contas deste texto ganham sentido quando os valores vêm do input().