Skip to content
This page has been auto-translated and may contain errors.View in English

Números e aritmética

Números aparecem em quase todo programa que você escreve. Um carrinho de compras soma um preço. Um jogo atualiza uma pontuação. Um script conta quantas vezes algo aconteceu. Python oferece operadores aritméticos que funcionam como matemática no papel, mais alguns extras que valem a pena conhecer desde o início.

Os operadores aritméticos do Python cobrem o conjunto padrão mais divisão inteira, módulo e exponenciação. Alguns comportamentos diferem de outras linguagens de forma que importa na prática: / sempre retorna um float, divisão por piso arredonda em direção ao infinito negativo, e módulo segue a semântica verdadeira de módulo.

Inteiros em Python não têm overflow (o comportamento de envolvimento ou erro que você pega em linguagens com inteiros de tamanho fixo): crescem tanto quanto a memória permite. Floats são os decimais de dupla precisão usuais, suficientes para a maioria dos trabalhos mas nunca exatos para dinheiro. Os operadores aritméticos seguem definições matemáticas em vez da convenção C que muitas linguagens copiam: // é divisão por piso (arredonda em direção ao infinito negativo) e % carrega o sinal do divisor, não do dividendo. Ambas as escolhas mantêm o mesmo resultado independentemente de seus inputs serem positivos ou negativos, que é o comportamento que você quer para ciclagem e envolvimento.

Os operadores

Os quatro operadores da matemática (+, -, *, /) funcionam exatamente como você espera. Python adiciona três mais que você usará constantemente: divisão inteira, resto e exponenciação.

Os quatro operadores padrão se comportam como esperado, com uma regra notável: / sempre retorna um float, mesmo quando o resultado é um número inteiro. Os três operadores adicionais estendem o que você consegue expressar sem trabalho extra.

Cada operador está ligado a um método dunder (um método nomeado com sublinhados duplos que Python chama nos bastidores): + para __add__, // para __floordiv__, % para __mod__, ** para __pow__, e assim por diante. O retorno prático é que suas próprias classes podem definir esses métodos e então trabalhar com + ou * diretamente, da mesma forma que um número embutido faz. Misturar um int e um float em uma operação sempre dá um float, e / retorna um float não importa o que você forneça.

python
price = 12.99
quantity = 3

print(price * quantity)   # 38.97
print(price + 2)          # 14.99
print(price - 1.00)       # 11.99
OperadorNomeExemploResultado
+Adição5 + 38
-Subtração5 - 32
*Multiplicação5 * 315
/Divisão5 / 31.6666...
//Divisão inteira5 // 31
%Resto5 % 32
**Exponenciação5 ** 3125
JunoOs operadores+, -, *, / funcionam como matemática no papel. Os três extras valem a pena aprender cedo: // divide até um número inteiro, % te dá o resto, e ** eleva a uma potência. Uso % muito mais do que esperava.
JunoOs operadores Os quatro básicos funcionam como esperado, com uma regra para guardar: / sempre retorna um float. Os extras são // para divisão inteira, % para o resto, e ** para exponenciação. Cada um poupa você de escrever uma função auxiliar.
JunoOs operadores Todo operador encaminha para um dunder, então uma classe que define __add__ ou __mul__ se conecta direto ao + e *. int e float misturados sempre alargam para float, e / retorna um float independentemente do que você dê a ele.

Divisão: / vs //

/ sempre te dá o resultado decimal exato, mesmo se a resposta é um número inteiro. // descarta a parte fracionária e arredonda em direção ao infinito negativo. Para números positivos significa cortar o decimal, mas para negativos vai um passo mais longe do zero:

/ sempre retorna um float, independentemente de os inputs serem inteiros. // retorna o piso do resultado: o maior inteiro que é menor ou igual ao resultado verdadeiro. Para números positivos é a mesma coisa que truncamento. Para negativos, não é:

/ é divisão verdadeira e sempre retorna um float. // é divisão por piso: arredonda o quociente verdadeiro em direção ao infinito negativo em vez de cortar em direção ao zero, que é o que muitas outras linguagens fazem. A razão pela qual importa na prática: // e % do Python satisfazem a == (a // b) * b + (a % b) para toda entrada inteira, negativos inclusos. Divisão truncante quebra essa identidade para negativos, então qualquer lógica de ciclagem ou envolvimento que você escreve fica correta aqui sem caso especial do sinal.

python
10 / 2     # 5.0   (sempre float, mesmo quando divide exatamente)
10 / 3     # 3.3333333333333335

10 // 3    # 3
7 // 2     # 3
-7 // 2    # -4    (arredonda em direção ao infinito negativo, não ao zero)

Você vai usar // principalmente com números positivos. Tenha o comportamento negativo em mente para quando eles aparecerem.

JunoDivisão: / vs /// sempre devolve um decimal, mesmo quando divide exatamente: 4 / 2 é 2.0. // descarta a parte fracionária, mas cuidado com os negativos: -7 // 2 é -4, não -3, porque arredonda em vez de cortar. Me pegou na primeira vez.

Python chama isso divisão por piso porque aplica a função piso matemática. Outras linguagens cortam em direção ao zero em vez disso, dando um resultado diferente para negativos. O nome // é uma dica: divida, então aplique piso.

JunoDivisão: / vs /// sempre retorna um float, até 4 / 22.0. // arredonda em direção ao piso em vez de truncar, então -7 // 2 é -4. Para números positivos os dois parecem iguais, a diferença só aparece com negativos.

// computa floor(a / b), não truncamento. Funciona em floats também: 7.5 // 2 é 3.0, o quociente com piso devolvido como um float em vez de um int.

JunoDivisão: / vs //// aplica piso ao quociente, então satisfaz a == (a // b) * b + (a % b) em toda entrada, negativos e tudo. Essa é a propriedade para contar em lógica de ciclagem. Note que um operando float faz // retornar um float, como 7.5 // 2 dando 3.0.

O operador resto %

% te dá o que sobra depois da divisão inteira. Se 10 // 3 é 3 (porque 3 cabe em 10 três vezes), então 10 % 3 é 1 (porque 3 × 3 = 9, e 10 - 9 = 1). O uso mais comum é verificar se um número é par ou ímpar.

% é o operador módulo. Verificar par/ímpar é o uso mais comum, mas generaliza para qualquer problema de ciclagem ou envolvimento: manter um contador dentro de um intervalo, distribuir itens entre grupos, repetir uma sequência. O padrão é sempre value % limit, que retorna algo entre 0 e limit - 1.

% do Python é módulo verdadeiro: o resultado sempre carrega o sinal do divisor. Muitas outras linguagens pegam o sinal do dividendo em vez disso, então dariam -1 onde Python dá 2 para -7 % 3. A resposta do Python sai de definir módulo como a - (a // b) * b com // arredondando em direção ao infinito negativo. O retorno é que value % limit fica dentro de 0 a limit - 1 mesmo quando value fica negativo, então um índice que envolve ao redor do fim de uma lista fica em alcance sem uma cláusula de proteção.

python
10 % 3    # 1
10 % 2    # 0  (divide exatamente)
10 % 7    # 3

6 % 2     # 0  (par)
7 % 2     # 1  (ímpar)
JunoO operador resto %% é o que sobra depois da divisão inteira. 10 % 3 é 1 porque 3 cabe em 10 três vezes com 1 sobrando. Você vai conhecê-lo principalmente como o teste par/ímpar: n % 2 é 0 para par, 1 para ímpar.
JunoO operador resto %% é módulo, e funciona bem além de par/ímpar: qualquer vez que você precise manter um valor dentro de um intervalo, value % limit o envolve de 0 até limit - 1. Contadores, atribuição de grupo, ciclos repetidos, tudo tem a mesma forma.
JunoO operador resto %% segue o sinal do divisor, então -7 % 3 é 2, não -1. Isso é o que permite value % limit ficar em alcance com inputs negativos, sem cláusula de proteção para um índice de envolvimento.

Exponenciação **

** eleva um número a uma potência. Use dois asteriscos, não o símbolo ^ (que significa outra coisa em Python):

** é exponenciação. Funciona com floats também, o que permite expressar raízes como potências fracionárias em vez de uma chamada de função separada:

** eleva a uma potência, e a forma de potência fracionária é prática: n ** 0.5 é uma raiz quadrada sem importar nada. Dois operandos int dão um int, qualquer operando float dá um float. Uma coisa a saber antes de usar em trabalho grande ou preciso: 9 ** 0.5 passa por matemática float, então pode pousar em 2.9999999999999996 para alguns inputs. Quando exatidão importa, math.isqrt() para raízes inteiras e math.pow() são as ferramentas a considerar, cobertas no capítulo Módulos.

python
2 ** 10    # 1024
3 ** 3     # 27
9 ** 0.5   # 3.0  (raiz quadrada: eleve à potência de 0.5)
JunoExponenciação **** eleva um número a uma potência, então 2 ** 10 é 1024. Uma potência fracionária te dá uma raiz: 9 ** 0.5 é 3.0. A armadilha é o símbolo, use **, não ^, que faz algo não relacionado em Python.
JunoExponenciação **** é exponenciação, e recebe floats, então 9 ** 0.5 te dá uma raiz quadrada sem chamada de função separada. Use a forma de potência fracionária quando quer uma raiz rápida inline.
JunoExponenciação ** Dois ints dão um int, qualquer float dá um float. A pegadinha com o truque ** 0.5 raiz é que passa por matemática float e pode oscilar, então use math.isqrt() ou math.pow() quando exatidão importa.

Precedência de operadores

Python segue a ordem de matemática padrão: exponenciação primeiro, então multiplicação e divisão, então adição e subtração. Quando você não tem certeza, use parênteses. Eles deixam a intenção clara e não custam nada:

Python segue a ordem PEMDAS/BODMAS padrão. A parte que confunde pessoas: /, //, e % todos compartilham o mesmo nível de precedência e avaliam da esquerda para a direita quando misturados. Parênteses são gratuitos; use-os sempre que a ordem não está clara à primeira vista:

Precedência do mais alto para o mais baixo entre operadores aritméticos: **, então menos unário (um sinal de menos na frente de um valor único), então * / // % (da esquerda para a direita quando compartilham um nível), então + -. A armadilha que pega no código real: -2 ** 2 é -(2 ** 2), que é -4, porque ** se liga mais forte que o menos na frente. Se você já quadra um valor que pode ser negativo, coloque parênteses como (-2) ** 2 ou o sinal estará errado sem erro para avisar você.

python
2 + 3 * 4      # 14, não 20
2 ** 3 + 1     # 9,  não 512
10 - 4 / 2     # 8.0, não 3.0

(2 + 3) * 4    # 20
10 / (2 + 3)   # 2.0
JunoPrecedência de operadores Mesma ordem que matemática no papel: potências primeiro, então multiplicar e dividir, então somar e subtrair. Quando a ordem não está clara à primeira vista, adicione parênteses. Eles não custam nada e deixam claro exatamente o que você quer dizer.
JunoPrecedência de operadores Ordem PEMDAS padrão, com um problema: /, // e % todos no mesmo nível e rodam da esquerda para a direita quando misturados. Essa regra da esquerda para a direita é a parte que as pessoas mal leem, então coloque parênteses sempre que o agrupamento não está claro.
JunoPrecedência de operadores A armadilha é o menos unário se ligando mais fraco que **, então -2 ** 2 é -4. Quadre qualquer coisa que possa ser negativa como (-2) ** 2, ou o sinal vira sem erro para sinalizar.

Como int e float interagem

Python tem uma regra consistente: / sempre retorna um decimal, mesmo 4 / 22.0. Qualquer operação misturando um inteiro e um decimal também dá um decimal. Quando você precisa de um número inteiro, use // ou converta com int().

As regras de tipo são previsíveis: / sempre retorna float. // e % com dois inteiros retornam int. Qualquer operação misturando int e float retorna float. Isso significa 4 / 2 é 2.0, não 2, que importa quando você precisa de um inteiro (por exemplo, para usar como índice).

A regra é fixa e vale a pena internalizar: int alarga para float sempre que os dois se misturam, / sempre retorna um float, e // retorna um int só quando ambos operandos são int. O bug que isso previne é um float escapando para algo que precisa de um número inteiro, como um índice de lista ou uma chave de dicionário, onde 2.0 e 2 não são intercambiáveis. Quando um cálculo pode produzir um float e você precisa de um int, converta com int() naquele ponto em vez de esperar que a divisão saiu inteira.

python
4 / 2      # 2.0   (float, sempre)
4 // 2     # 2     (int)
4 + 2      # 6     (int)
4 + 2.0    # 6.0   (float)
4 * 0.5    # 2.0   (float)
JunoComo int e float interagem/ sempre dá um decimal, então 4 / 2 é 2.0, não 2. Misture um número inteiro com um decimal em qualquer lugar e você recebe um decimal. Quando você precisa de um número inteiro, procure por // ou coloque em int().
JunoComo int e float interagem/ é sempre float, // e % em dois ints ficam int, e qualquer int misturado com um float sai float. O que pega pessoas é 4 / 2 ser 2.0 quando você queria um índice.
JunoComo int e float interagem Um float errado de / quebra qualquer coisa que precisa de um int exato, como um índice ou chave de dict onde 2.0 não é 2. Converta com int() naquele limite em vez de confiar que a divisão saiu inteira.

Precisão de float

Há uma pegadinha que surpreende quase todo mundo em algum ponto:

python
0.1 + 0.2   # 0.30000000000000004

Esse minúsculo erro não é um bug em Python. Computadores armazenam números decimais em binário, e alguns valores como 0.1 não podem ser representados exatamente. É similar a como 1/3 não pode ser escrito exatamente em decimal. Para a maioria dos cálculos cotidianos não importa. Para exibir dinheiro, round() ou o especificador de formato :.2f vai manter a saída arrumada.

Floats te dão aproximadamente 15 a 16 dígitos decimais significativos de precisão. A imprecisão aparece porque algumas frações não podem ser armazenadas exatamente em binário, então 0.1 + 0.2 produz 0.30000000000000004. A oscilação só aparece quando você inspeciona o valor bruto; formatar com :.2f ou round() a esconde na saída.

Para trabalho financeiro onde frações de centavo se acumulam, Python fornece decimal.Decimal na biblioteca padrão com aritmética exata em base 10. Isso é coberto no capítulo Módulos.

Um float armazena números em binário (base 2), e qualquer fração cujo denominador não é uma potência de dois (como 1/10) não tem forma binária exata, da mesma forma que 1/3 não tem forma decimal exata. Essa é a razão inteira pela qual 0.1 + 0.2 pousa em 0.30000000000000004. O erro por operação é minúsculo, mas se acumula ao longo de uma longa cadeia de aritmética, então duas formas de computar o mesmo total podem discordar nos últimos poucos dígitos.

A regra que previne o bug: nunca use um float para dinheiro, e nunca teste floats para igualdade exata com ==. Procure por decimal.Decimal quando você precisa de aritmética exata em base 10 (faturamento, contabilidade), ou fractions.Fraction quando você precisa de razões exatas sem arredondamento algum. Ambos vêm na biblioteca padrão do Python, cobertos no capítulo Módulos.

JunoPrecisão de float Computadores armazenam decimais em binário, e alguns valores como 0.1 não têm forma binária exata, então 0.1 + 0.2 sai como 0.30000000000000004. Não é um bug em Python, toda linguagem faz isso. Para saída cotidiana, round() ou :.2f mantém arrumado.
JunoPrecisão de float Binário não consegue segurar todo decimal exatamente, então 0.1 + 0.2 oscila para 0.30000000000000004. Bom para a maioria da matemática, e :.2f ou round() arruma a exibição. Quando os centavos têm que somar, mude para decimal.Decimal.
JunoPrecisão de float A regra que te salva: nenhum float para dinheiro, e nunca == em floats, já que o erro se acumula ao longo de uma cadeia de operações. Use decimal.Decimal para base 10 exata e fractions.Fraction para razões exatas.

Literais numéricos legíveis

Python permite colocar sublinhados em literais numéricos para deixar números grandes mais legíveis. Python os ignora completamente; eles estão lá para você:

Sublinhados são válidos em qualquer lugar em um literal numérico e são removidos durante parsing sem efeito no valor. Útil para separadores de milhares em constantes e para agrupar dígitos em literais binários ou hexadecimais:

Sublinhados são removidos antes de Python ver o valor, então têm zero efeito nele. Funcionam em inteiros, floats, e literais baseados igualmente (0xFF_FF, 0b1010_0001, 1_234.567_890), o que os torna práticos para agrupar bytes em uma constante hexadecimal, não só milhares em uma decimal. As únicas restrições: um sublinhado não pode ficar no início, no fim, ou próximo a um ponto decimal ou marcador de expoente.

python
population = 8_100_000_000
distance_km = 384_400
pi_approx = 3.141_592_653
JunoLiterais numéricos legíveis Coloque sublinhados em um número longo para deixá-lo legível: 8_100_000_000 é o mesmo valor que 8100000000. Python os ignora completamente, estão lá para seus olhos, não para o interpretador.
JunoLiterais numéricos legíveis Sublinhados são válidos em qualquer lugar dentro de um literal numérico e desaparecem no tempo de parse, então o valor não muda. Bom para separadores de milhares em constantes, e igualmente útil para agrupar dígitos em binário ou hex.
JunoLiterais numéricos legíveis Sublinhados são cosmética em inteiros, floats e literais baseados, então 0xFF_FF e 0b1010_0001 leem mais limpo. As únicas regras: não no início, fim, ou perto de ponto decimal ou marcador de expoente.

Funções embutidas úteis

abs()

abs() retorna o valor absoluto: sempre positivo, independentemente do sinal do input. Use-o quando você se importa com o quão longe um número está de zero, não qual direção.

abs() retorna a magnitude de um número. Funciona em inteiros e floats. Útil para cálculos de distância, margens de erro, e qualquer situação onde direção é irrelevante e você só precisa do tamanho do valor.

abs() retorna a magnitude de um número, com o tipo de retorno combinando o input: um int dentro dá um int fora, um float dá um float. O uso cotidiano é comparar o quão longe dois valores ficam de um alvo sem se importar qual lado eles caem, por exemplo abs(measured - expected) < tolerance como um teste de tolerância, que lê mais claramente que duas comparações contra um intervalo assinado.

python
abs(-5)     # 5
abs(3.7)    # 3.7
abs(-0.5)   # 0.5
Junoabs()abs() remove o sinal e devolve o tamanho positivo: abs(-5) é 5, abs(3.7) é 3.7. Use quando você se importa o quão longe um número está de zero, não qual direção se inclina.
Junoabs()abs() dá a magnitude de um int ou float, direção descartada. É a forma limpa de escrever testes de distância e margem de erro, qualquer lugar onde o sinal não é parte da questão.
Junoabs()abs() mantém o tipo de input, um int fica um int. O padrão que vale a pena guardar é abs(measured - expected) < tolerance: um teste de tolerância em vez de duas comparações ao redor de um intervalo assinado.

round()

round() arredonda para o inteiro mais próximo por padrão. Passe um segundo argumento para manter um número específico de casas decimais:

python
round(3.7)          # 4
round(3.2)          # 3
round(3.14159, 2)   # 3.14

Uma coisa que vale a pena saber: round(2.5)2, não 3. Python arredonda para o número par mais próximo quando um valor está exatamente no meio entre duas opções.

round() usa arredondamento do banqueiro: quando o valor está exatamente no meio, arredonda para o número par mais próximo em vez de sempre arredondar para cima. Isso minimiza erro acumulado em trabalho estatístico mas pode surpresá-lo se você espera 0.5 sempre arredondar para cima:

python
round(2.5)   # 2  (arredonda para par mais próximo)
round(3.5)   # 4
round(4.5)   # 4  (não 5)
round(3.14159, 2)   # 3.14

round() usa arredondamento-meio-para-par (arredondamento do banqueiro): um empate exato vai para o inteiro par mais próximo, não sempre para cima. Isso mantém erros de arredondamento de tendenciar uma longa coluna de figuras em uma direção, é por isso que é o padrão para trabalho estatístico. Duas precauções práticas. Primeiro, um empate float muitas vezes não é um empate exato uma vez que está em binário, então round(2.675, 2)2.67, não 2.68, porque 2.675 não pode ser armazenado exatamente. Segundo, quando você precisa de arredondamento de moeda previsível, faça com decimal.Decimal e um modo de arredondamento explícito em vez de confiar em round() sobre floats.

python
round(2.5)   # 2
round(3.5)   # 4
round(4.5)   # 4
Junoround()round(x) vai para o número inteiro mais próximo, round(x, n) mantém n casas decimais. A surpresa: um valor exatamente no meio arredonda para o número par mais próximo, então round(2.5) é 2, não 3.
Junoround()round() usa arredondamento do banqueiro, então meios exatos vão para o número par mais próximo: round(2.5) é 2, round(4.5) é 4. Corta tendência em trabalho agregado, mas espere isso quando você assumiu que meios sempre arredondam para cima.
Junoround() Arredondamento do banqueiro mais binário significa round(2.675, 2) é 2.67, já que 2.675 não é um empate exato sob o capô. Para moeda, arredonde com decimal.Decimal e um modo escolhido em vez de confiar em round() sobre floats.

divmod()

divmod() te dá tanto o quociente quanto o resto em uma única chamada. Retorna um par de valores, uma tupla (coberta no capítulo Tuplas e conjuntos), que você pode atribuir a dois nomes de uma vez:

divmod(a, b) é equivalente a (a // b, a % b) mas computado em um único passo. Use quando você precisa dos dois valores mesmo assim: paginação, conversão de tempo, ou distribuição de itens em grupos.

divmod(a, b) faz a divisão uma vez e retorna tanto o quociente piso quanto o resto módulo como um par, então você evita recomputar a mesma divisão através de // e então %. Lê mais limpo nos lugares onde você precisa de ambas as metades mesmo assim: conversão de tempo (divmod(seconds, 60)), paginação, ou layout de itens em linhas de tamanho fixo.

python
divmod(10, 3)   # (3, 1): quociente 3, resto 1
divmod(7, 2)    # (3, 1)
divmod(9, 3)    # (3, 0)

quotient, remainder = divmod(10, 3)
print(quotient)    # 3
print(remainder)   # 1
Junodivmod()divmod(a, b) te devolve o quociente e o resto juntos: divmod(10, 3) é (3, 1). Você pode desempacotar ambos de uma vez com quotient, remainder = divmod(10, 3).
Junodivmod()divmod(a, b) é (a // b, a % b) em um passo. Procure por isso quando você precisa de ambas as peças, como conversão de tempo ou paginação, em vez de computar a divisão duas vezes.
Junodivmod() Uma divisão, ambos resultados: divmod() pula o trabalho redundante de separado // e %. Lê melhor onde você quer ambas as metades mesmo assim, como divmod(seconds, 60) ou layout de linha.

Na prática

Uma calculadora de gorjeta:

python
bill = 45.50
tip_rate = 0.18
tip = round(bill * tip_rate, 2)
total = round(bill + tip, 2)

print(f"Bill:  ${bill}")
print(f"Tip:   ${tip}")
print(f"Total: ${total}")

round() mantém a saída parecendo dinheiro em vez de uma longa sequência de casas decimais.

Contando páginas para paginação e rastreando progresso como porcentagem:

python
total_items = 153
items_per_page = 10

full_pages, leftover = divmod(total_items, items_per_page)
total_pages = (total_items + items_per_page - 1) // items_per_page

print(f"Full pages: {full_pages}, leftover: {leftover}")
print(f"Total pages needed: {total_pages}")   # 16
python
total_files = 847
processed_files = 312

percent = round(processed_files / total_files * 100, 1)
print(f"Progress: {processed_files}/{total_files} ({percent}%)")

A fórmula de divisão de teto (n + d - 1) // d é um truque inteiro padrão para arredondar para cima sem converter para float.

Normalização min-max e mudança de porcentagem: dois padrões que aparecem constantemente em trabalho de dados:

python
# normalização min-max: escale um valor no intervalo 0.0 a 1.0
value = 75
minimum = 0
maximum = 100

normalised = (value - minimum) / (maximum - minimum)
print(f"Normalised: {normalised:.2f}")   # 0.75

# mudança de porcentagem entre duas medições
before = 1_200
after = 1_380

change = (after - before) / before * 100
print(f"Change: {change:.1f}%")          # 15.0%

Ambos padrões reduzem a uma razão: um valor relativo a um intervalo de referência ou uma magnitude de referência. A precisão de float é suficiente para a maioria do trabalho analítico; o erro acumulado só importa quando a computação encadeia dezenas de operações ou envolve valores que diferem por muitas ordens de magnitude.