Curso de Python / Inteiros, floats e conversão de números

Em Python, int representa números inteiros, e float representa números de ponto flutuante binário. Para valores que exigem regras decimais exatas, use unidades inteiras ou Decimal e defina explicitamente a unidade, a precisão e o arredondamento.

Leia os operadores aritméticos com precisão

Expressão Operação Resultado
7 / 2 Divisão 3.5
7 // 2 Divisão pelo piso 3
7 % 2 Resto da divisão 1
2 ** 3 Potenciação 8

Com inteiros, // produz o piso do quociente: o inteiro menor ou igual ao resultado da divisão. Ele não corta simplesmente a parte fracionária em direção a zero. Por isso, -7 // 2 vale -4, enquanto int(-3.5) vale -3. Essa diferença importa quando o cálculo envolve valores negativos.

Use parênteses quando a prioridade dos operadores não deixar a intenção clara. Os inteiros Python não têm um limite fixo de 32 bits, embora os recursos de memória sejam finitos. A escolha de um tipo numérico também deve considerar os limites dos arquivos, bancos de dados ou serviços com que o programa vai trocar informações.

Execute uma comparação completa dos tipos numéricos

Salve o código abaixo em UTF-8 como numeric_demo.py, na pasta do projeto. Execute python numeric_demo.py com o ambiente selecionado. No macOS ou Ubuntu, fora de um ambiente virtual, use python3 se esse for o nome do interpretador. decimal faz parte da biblioteca padrão; não é necessário instalar um pacote.

from decimal import Decimal

print(7 / 2, 7 // 2, 7 % 2)
print(-7 // 2, int(-3.5))
print(0.1 + 0.2 == 0.3)
print(Decimal("0.1") + Decimal("0.2"))
price_won = 3500
print(price_won * 3)

A saída esperada é:

3.5 3 1
-4 -3
False
0.3
10500

A primeira linha compara divisão, divisão pelo piso e resto. A segunda mostra a diferença entre piso e truncamento. A terceira é False porque as aproximações binárias de 0.1, 0.2 e 0.3 não satisfazem essa igualdade exata depois da soma. A quarta usa valores decimais criados a partir de strings. A última calcula três unidades de um preço inteiro.

O problema da representação binária não é exclusivo de Python. A explicação oficial sobre ponto flutuante mostra por que muitas frações decimais precisam ser aproximadas. Isso não torna float inútil: o tipo é adequado a muitos cálculos aproximados, desde que as comparações e tolerâncias sejam escolhidas para o problema.

Escolha a conversão e a precisão de que precisa

int("3500") interpreta uma string que representa um inteiro. int("3.5") falha, mas int(3.5) recebe um número e trunca sua parte fracionária. float("3.5") cria um valor de ponto flutuante. Assim, o tipo do argumento faz parte do significado da conversão; não basta olhar os caracteres exibidos.

Formatar não é converter a aritmética para um modelo decimal exato. format(0.1 + 0.2, ".2f") produz a string "0.30", mas não modifica os valores usados na soma nem a representação do resultado. Use a formatação para apresentar a informação e um tipo apropriado para realizar o cálculo.

Decimal oferece aritmética decimal com precisão e arredondamento configuráveis. Prefira construir valores a partir de strings, como Decimal("0.1"). Usar Decimal(0.1) transfere para o decimal o valor da aproximação binária já presente no float.

Decimal não elimina a necessidade de uma política: divisões como um terço ainda exigem precisão finita e podem ser arredondadas. Defina a quantidade de casas e a regra de arredondamento de acordo com o cálculo. Uma quantidade mostrada com duas casas não prova que todas as etapas anteriores seguiram essa mesma regra.

Verifique as unidades e os casos de erro

No exemplo, price_won = 3500 representa um valor em won inteiros. Para dados em centavos, outra opção é armazenar a quantidade inteira de centavos, mantendo essa unidade explícita. Valores de moedas ou unidades diferentes não devem ser somados sem uma regra de conversão; o tipo numérico não decide essa política sozinho.

  1. Compare -7 // 2 com -7 / 2. O primeiro resultado é -4, e o segundo é -3.5.
  2. Em uma expressão do exemplo que divide por 2, troque somente o divisor por 0. Observe ZeroDivisionError, depois restaure o divisor antes de continuar.
  3. Tente converter a string "3500 KRW" com int(). Ela não representa apenas um inteiro e provoca ValueError. Não remova caracteres sem definir quais formatos a entrada deve aceitar.
  4. Restaure o programa original e confira novamente as cinco linhas de saída.

A aula de entrada e conversão de uma despesa mostra onde o texto digitado se transforma em número. Use esse ponto do programa para aplicar as regras de formato e unidade, em vez de esperar que uma conversão bem-sucedida também valide todas as regras do cadastro.