Tipos numéricos
Esta aula aborda os tipos numéricos em Python: int, float e complex, suas operações básicas, diferenças entre divisão real e inteira, e questões de precisão e arredondamento. O conteúdo inclui exemplos práticos, boas práticas e exercícios para fixação.
Nesta aula, vamos explorar os tipos numéricos fundamentais em Python: inteiros (int), ponto flutuante (float) e números complexos (complex). Entender como esses tipos funcionam é essencial para realizar cálculos precisos e eficientes. Além disso, discutiremos as operações aritméticas básicas, a diferença entre divisão real e inteira, e como lidar com precisão e arredondamento.
Python oferece suporte nativo a números inteiros de precisão arbitrária, números de ponto flutuante (seguindo o padrão IEEE 754) e números complexos com parte real e imaginária. Vamos ver cada um deles em detalhes.
int, float, complex
O tipo int representa números inteiros, positivos ou negativos, sem limite de tamanho (depende apenas da memória disponível). Já o tipo float representa números reais com ponto flutuante, normalmente com precisão de 64 bits (double). O tipo complex representa números complexos, com uma parte real e uma imaginária, escritos na forma a + bj (onde j é a unidade imaginária).
Exemplos de criação:
# int
idade = 30
numero_grande = 123456789012345678901234567890
# float
altura = 1.75
pi = 3.141592653589793
notacao_cientifica = 1.5e-3 # 0.0015
# complex
z = 2 + 3j
w = complex(1, -4) # 1 - 4j
print(type(idade)) # <class 'int'>
print(type(altura)) # <class 'float'>
print(type(z)) # <class 'complex'>
Observe que números complexos são imutáveis e suportam operações aritméticas específicas.
Operações
Python oferece operadores aritméticos para todos os tipos numéricos: + (adição), - (subtração), * (multiplicação), / (divisão real), // (divisão inteira), % (módulo) e ** (exponenciação). Além disso, funções embutidas como abs(), pow(), divmod() e operadores de comparação também se aplicam.
Exemplos:
a = 10
b = 3
print(a + b) # 13
print(a - b) # 7
print(a * b) # 30
print(a / b) # 3.3333333333333335
print(a // b) # 3
print(a % b) # 1
print(a ** b) # 1000
# Com floats
x = 5.5
y = 2.0
print(x + y) # 7.5
print(x // y) # 2.0 (divisão inteira com float retorna float)
# Com complexos
z1 = 1 + 2j
z2 = 3 - 1j
print(z1 + z2) # (4+1j)
print(z1 * z2) # (5+5j)
print(z1 ** 2) # (-3+4j)
Operadores de comparação (==, !=, <, >, <=, >=) também funcionam, mas cuidado ao comparar floats devido a erros de precisão.
Divisão (/ vs //)
A divisão real (/) sempre retorna um float (mesmo que os operandos sejam inteiros e o resultado seja exato). Já a divisão inteira (//) retorna o quociente inteiro (floor) da divisão, descartando a parte fracionária. O tipo do resultado depende dos operandos: se ambos forem int, o resultado é int; se pelo menos um for float, o resultado é float (mas ainda assim um valor inteiro).
Exemplos:
# Divisão real
print(7 / 2) # 3.5
print(8 / 2) # 4.0 (sempre float)
# Divisão inteira
print(7 // 2) # 3
print(8 // 2) # 4
print(-7 // 2) # -4 (floor: -3.5 vai para -4)
print(7 // -2) # -4
# Divisão inteira com float
print(7.0 // 2) # 3.0
print(7 // 2.0) # 3.0
O operador // realiza o piso (floor) da divisão, ou seja, arredonda para baixo (em direção ao infinito negativo). Isso é importante para números negativos.
Precisão e arredondamento
Números float em Python seguem o padrão IEEE 754 (precisão dupla de 64 bits), o que significa que nem todos os números decimais podem ser representados exatamente. Por exemplo, 0.1 + 0.2 não é exatamente 0.3:
print(0.1 + 0.2) # 0.30000000000000004
Para lidar com precisão, podemos usar arredondamento com a função round(), formatação de strings ou o módulo decimal para aritmética decimal exata.
Função round():
print(round(3.14159, 2)) # 3.14
print(round(2.675, 2)) # 2.67 (cuidado: devido a precisão, pode arredondar para baixo)
print(round(2.5)) # 2 (banker's rounding: arredonda para o par mais próximo)
Formatação com f-strings:
valor = 123.456789
print(f"{valor:.2f}") # 123.46
print(f"{valor:.3f}") # 123.457
Módulo decimal:
from decimal import Decimal, getcontext
getcontext().prec = 4 # precisão de 4 dígitos
print(Decimal('0.1') + Decimal('0.2')) # 0.3
a = Decimal('1.234')
b = Decimal('5.678')
print(a + b) # 6.912
Para números muito grandes ou muito pequenos, float pode overflow ou underflow. Use int para inteiros grandes ou Decimal para precisão controlada.
Boas práticas
Evite comparações diretas de igualdade entre floats; use uma tolerância (math.isclose):
import math
print(math.isclose(0.1 + 0.2, 0.3)) # True
Prefira int para contagens e índices, e use float para medições científicas. Para cálculos financeiros, use Decimal.
Referências
- Documentação oficial: Tipos numéricos
- Tutorial Python: Números
- Módulo decimal
- Função round()
- math.isclose
- divmod()
Exercícios
- Escreva uma expressão que calcule a área de um círculo com raio 5. Use pi = 3.14159.
- Qual é o resultado de 17 // 5 e 17 % 5? Explique.
- Por que 0.1 + 0.2 não é igual a 0.3? Como você pode verificar se são aproximadamente iguais?
- Converta o número complexo (3+4j) para coordenadas polares (módulo e ângulo). Use funções do módulo cmath.
- Arredonde o número 2.675 para duas casas decimais usando round(). O resultado é o esperado? Explique.
area = 3.14159 * 5 ** 2 # 78.53975
17 // 5 = 3 (divisão inteira: 5 cabe 3 vezes em 17) e 17 % 5 = 2 (resto: 17 - 3*5 = 2).
Devido à representação binária de floats, 0.1 e 0.2 não são exatos. Para comparar, use math.isclose(0.1+0.2, 0.3).
import cmath
z = 3 + 4j
modulo, angulo = cmath.polar(z)
print(modulo, angulo) # 5.0, 0.9272952180016122 (radianos)
round(2.675, 2) retorna 2.67, não 2.68, devido à imprecisão do float (2.675 é na verdade 2.6749999999999998). Para arredondamento correto, use Decimal('2.675').quantize(Decimal('0.01')).