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

Números e aritmética

docs.scrimba.com

Números aparecem em quase todos os programas que você escreve. Um carrinho de compras totaliza 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 de papel, mais alguns 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 formas que importam na prática: / sempre retorna um float, divisão por piso arredonda em direção ao infinito negativo, e módulo segue semântica verdadeira de módulo.

Inteiros do Python não têm overflow (o comportamento de envolvimento ou erro que você encontra em linguagens com inteiros de tamanho fixo): eles crescem tão grande quanto a memória permite. Floats são os decimais duplos usuais de precisão, bons para a maioria do trabalho, mas nunca exatos para dinheiro. Os operadores aritméticos seguem definições matemáticas e não a 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ê esperaria. 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ê pode expressar sem trabalho extra.

Cada operador é 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 depois trabalhar com + ou * diretamente, da mesma forma que um número integrado 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ê alimentá-lo.

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+, -, *, / se comportam como matemática de papel. Os três extras valem a pena aprender desde o início: // divide até um número inteiro, % te dá o resto, e ** eleva a uma potência. Eu uso % muito mais do que jamais esperaria.
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 economiza você escrevendo um auxiliar.
JunoOs operadores Cada operador se encaminha para um dunder, então uma classe que define __add__ ou __mul__ se conecta direto em + e *. int e float misturados sempre se alargam para float, e / retorna um float independentemente do que você der.

Divisão: / vs //

/ sempre dá o resultado decimal exato, mesmo que a resposta seja um número inteiro. // cai a parte fracionária e arronda em direção ao infinito negativo. Para números positivos, isso significa cortar o decimal, mas para negativos, ele vai um passo mais longe de zero:

/ sempre retorna um float, independentemente de os inputs serem inteiros. // retorna o piso do resultado: o maior inteiro menor ou igual ao resultado verdadeiro. Para números positivos, isso é o mesmo 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 chocar em direção a zero, que é o que muitas outras linguagens fazem. A razão pela qual isso importa na prática: o // e % do Python satisfazem a == (a // b) * b + (a % b) para cada entrada inteira, negativos inclusos. Divisão truncada quebra essa identidade para negativos, então qualquer lógica de ciclagem ou envolvimento que você escrever permanece correta aqui sem casos especiais de sinal.

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

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

Você usará principalmente // com números positivos. Guarde o comportamento negativo em mente para quando aparecerem.

JunoDivisão: / vs /// sempre devolve um decimal, mesmo que divida evenly: 4 / 2 é 2.0. // cai a parte fracionária, mas cuidado com os negativos: -7 // 2 é -4, não -3, porque arronda em vez de chocar. Me pegou na primeira vez que fiz.

Python chama isso divisão por piso porque ela aplica a função de piso matemática. Outras linguagens cortam em direção a zero, dando um resultado diferente para negativos. O nome // é uma dica: divida, depois arredonde para baixo.

JunoDivisão: / vs /// sempre retorna um float, mesmo 4 / 22.0. // arronda para baixo em vez de truncar, então -7 // 2 é -4. Para números positivos os dois parecem iguais, a diferença só aparece em negativos.

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

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

O operador de resto %

% 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 de módulo. Verificação de par/ímpar é o uso mais comum, mas se 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.

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

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

6 % 2     # 0  (par)
7 % 2     # 1  (ímpar)
JunoO operador de resto %% é o resto depois da divisão inteira. 10 % 3 é 1 porque 3 cabe em 10 três vezes com 1 sobrando. Você o encontrará principalmente como a verificação de par/ímpar: n % 2 é 0 para par, 1 para ímpar.
JunoO operador de resto %% é módulo, e vai bem além de par/ímpar: qualquer hora que você precisa manter um valor dentro de um intervalo, value % limit o envolve de 0 através de limit - 1. Contadores, atribuição de grupo, ciclos repetidos, tudo a mesma forma.
JunoO operador de resto %% segue o sinal do divisor, então -7 % 3 é 2, não -1. Isso é o que deixa value % limit em intervalo com inputs negativos, nenhuma 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 algo diferente em Python):

** é exponenciação. Funciona com floats também, que permite você 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 você usá-lo em trabalho grande ou preciso: 9 ** 0.5 vai através da matemática de float, então pode desembarcar em 2.9999999999999996 para alguns inputs. Quando exatidão importa, math.isqrt() para raízes inteiras e math.pow() são as ferramentas para pesar, 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 única armadilha é o símbolo, use **, não ^, que faz algo não relacionado em Python.
JunoExponenciação **** é exponenciação, e leva floats, então 9 ** 0.5 te dá uma raiz quadrada sem chamada de função separada. Recorra à forma de potência fracionária quando você 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 ele roda através da matemática de float e pode se afastar, então recorra para math.isqrt() ou math.pow() quando exatidão conta.

Precedência de operador

Python segue a ordem matemática padrão: exponenciação primeiro, depois multiplicação e divisão, depois 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 as pessoas: /, //, e % todos compartilham o mesmo nível de precedência e avalia da esquerda para direita quando misturados. Parênteses são de graça; use-os sempre que a ordem não seja clara à primeira vista:

Precedência de mais alta para mais baixa entre operadores aritméticos: **, depois - unário (um sinal de menos na frente de um único valor), depois * / // % (da esquerda para direita quando compartilham um nível), depois + -. A única armadilha que morde em código real: -2 ** 2 é -(2 ** 2), que é -4, porque ** se vincula mais aperto que o menos à frente. Se você jamais elevar um valor que poderia ser negativo, colocá-lo entre parênteses como (-2) ** 2 ou o sinal estará errado sem erro algum 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 operador Mesma ordem que matemática de papel: potências primeiro, depois multiplicar e dividir, depois somar e subtrair. Quando a ordem não for clara à primeira vista, adicione parênteses. Eles não custam nada e deletam exatamente o que você quis dizer.
JunoPrecedência de operador Ordem PEMDAS padrão, com uma armadilha: /, // e % todos sentam no mesmo nível e rodam da esquerda para direita quando misturados. Essa regra da esquerda para direita é a parte que pessoas leem errado, então colocam entre parênteses sempre que o agrupamento não for claro.
JunoPrecedência de operador A armadilha é menos unário se vincular mais solto que **, então -2 ** 2 é -4. Eleve ao quadrado qualquer coisa que poderia ser negativa como (-2) ** 2, ou o sinal vira com nenhum erro para sinalizá-lo.

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 um número inteiro, use // ou converta com int().

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 um inteiro (por exemplo, para usar como índice).

A regra é fixa e vale a pena internalizar: int se alarga para float sempre que os dois se misturam, / sempre retorna um float, e // retorna um int apenas quando ambos os operandos são int. O bug que isso previne é um float se esgueirando em algo que precisa um número inteiro, como um índice de lista ou chave de dicionário, onde 2.0 e 2 não são intercambiáveis. Quando um cálculo poderia produzir um float e você precisa 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ê pega um decimal fora. Quando você precisa um número inteiro, recorra a // ou envolva em int().
JunoComo int e float interagem/ é sempre float, // e % em dois ints permanecem int, e qualquer int misturado com um float sai float. O que pega pessoas é 4 / 2 sendo 2.0 quando você queria um índice.
JunoComo int e float interagem Um float vadio de / quebra qualquer coisa que precisa um `int` exato, como um índice ou chave dict onde 2.0 não é 2. Converta com int() naquele limite em vez de confiar na divisão para sair inteira.

Precisão de float

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

python
0.1 + 0.2   # 0.30000000000000004

Aquele pequeno erro não é um bug do 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 manterá a saída arrumada.

Floats te dão aproximadamente 15 a 16 dígitos significativos de precisão decimal. 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 deriva só aparece quando você inspeciona o valor bruto; formatação com :.2f ou round() a esconde na saída.

Para trabalho financeiro onde frações de centavo acumulam, Python fornece decimal.Decimal na biblioteca padrão com aritmética exata 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 exata de binário, da mesma forma que 1/3 não tem forma exata de decimal. Essa é a razão inteira pela qual 0.1 + 0.2 desembarca em 0.30000000000000004. O erro por operação é minúsculo, mas acumula através de uma longa cadeia de aritmética, então duas formas de calcular o mesmo total podem discordar nos últimos dígitos.

A regra que previne o bug: nunca use um float para dinheiro, e nunca teste floats para igualdade exata com ==. Recorra a decimal.Decimal quando você precisa aritmética exata base-10 (cobrança, contabilidade), ou fractions.Fraction quando você precisa ratios exatos sem arredondamento algum. Ambos viajam 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 exata de binário, então 0.1 + 0.2 sai como 0.30000000000000004. Não é um bug do Python, toda linguagem faz isso. Para saída cotidiana, round() ou :.2f mantém arrumado.
JunoPrecisão de float Binário não pode manter cada decimal exatamente, então 0.1 + 0.2 se afasta 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 a salva: nenhum float para dinheiro, e nunca == em floats, desde que o erro acumula através de uma cadeia de operações. Use decimal.Decimal para base-10 exata e fractions.Fraction para ratios exatos.

Literais de número legíveis

Python deixa você colocar sublinhados em literais de número para fazer 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 retirados durante análise com nenhum efeito no valor. Útil para separadores de milhares em constantes e para agrupar dígitos em literais binários ou hex:

Sublinhados são retirados antes do Python ver o valor, então eles têm efeito zero nele. Eles funcionam em inteiros, floats, e literais baseados alike (0xFF_FF, 0b1010_0001, 1_234.567_890), que os torna práticos para agrupar bytes em uma constante hex, não apenas milhares em uma decimal. As únicas restrições: um sublinhado não pode sentar no início, no final, ou perto de um ponto decimal ou marcador de expoente.

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

Funções integradas úteis

abs()

abs() retorna o valor absoluto: sempre positivo, independentemente do sinal do input. Use-o quando você se importa como longe um número é 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ê apenas 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 como dois valores distante sentam de um alvo sem se importar qual lado eles caem em, por exemplo abs(measured - expected) < tolerance como uma verificação 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() tira o sinal e devolve o tamanho positivo: abs(-5) é 5, abs(3.7) é 3.7. Recorra a ele quando você se importa como longe um número é 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 distância e verificações de margem de erro, em qualquer lugar que o sinal não seja parte da pergunta.
Junoabs()abs() mantém o tipo de input, um `int` permanece um `int`. O padrão que vale manter é abs(measured - expected) < tolerance: uma verificação 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 de duas opções.

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

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

round() usa round-half-to-even (arredondamento de banqueiro): um empate exato vai para o inteiro par mais próximo, não sempre para cima. Isso impede que erros de arredondamento enviesem uma coluna longa de figuras em uma direção, que é por que é o padrão para trabalho estatístico. Duas advertências práticas. Primeiro, um empate float frequentemente 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 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 sentando exatamente no meio arronda para o número par mais próximo, então round(2.5) é 2, não 3.
Junoround()round() usa arredondamento de banqueiro, então empates exatos vão para o número inteiro par mais próximo: round(2.5) é 2, round(4.5) é 4. Isso corta viés em trabalho agregado, mas espere quando você assumiu empates sempre arredondam para cima.
Junoround() Arredondamento de banqueiro mais binário significa round(2.675, 2) é 2.67, desde 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() 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 ao mesmo tempo:

divmod(a, b) é equivalente a (a // b, a % b) mas computado em um único passo. Use-o quando você precisa ambos os valores de qualquer forma: paginação, conversão de tempo, ou distribuindo itens em grupos.

divmod(a, b) faz a divisão uma vez e retorna tanto o quociente de piso quanto o resto de módulo como um par, então você evita recomputar a mesma divisão através de // e depois %. Lê mais limpo nos lugares que você precisa ambas as metades de qualquer forma: conversão de tempo (divmod(seconds, 60)), paginação, ou disposição de itens através de 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) devolve o quociente e o resto juntos: divmod(10, 3) é (3, 1). Você pode desempacotar ambos ao mesmo tempo com quotient, remainder = divmod(10, 3).
Junodivmod()divmod(a, b) é (a // b, a % b) em um passo. Recorra a ele quando você precisa ambos os pedaços, como conversão de tempo ou paginação, em vez de computar a divisão duas vezes.
Junodivmod() Uma divisão, ambos os resultados: divmod() pula o trabalho redundante de `/` e `%` separados. Lê melhor onde você quer ambas as metades de qualquer forma, como divmod(seconds, 60) ou disposição 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 série de casas decimais.

Contando páginas para paginação e rastreando progresso como uma 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 na faixa de 0.0 para 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 os 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 apenas importa quando a computação encadeia dúzias de operações ou envolve valores que diferem por muitas ordens de magnitude.