Entendendo números racionais na prática
A gente cresce achando que número é coisa do primário, mas na hora de implementar uma solução real, frações e decimais aparecem do nada e estragam tudo se você não souber o que estão fazendo. Números racionais são simplesmente aqueles que podem ser escritos como uma razão entre dois inteiros, ou seja, na forma a/b onde b é diferente de zero. Parece bobo falar isso, mas a maioria das pessoas trava exatamente aqui quando o denominator vira uma sequência infinita de dígitos. Eu já vi engenheiro júnior perder meia manhã porque o sistema dele estava somando frações com denominadores diferentes e o resultado sempre saía errado. O problema era simples: ele não tinha pensado em encontrar o mmc antes de juntar os termos. Quando você tem 3/7 mais 5/11, o denominador comum certo é 77, não 18 ou 88 como ele chutou no código. A correção foi trivial, mas o tempo gasto pra descobrir foi desnecessário.
O que numeros racionais realmente significam fora da teoria
Na prática, o que importa é saber lidar com a representação interna. O Python tem o módulo fractions que trabalha com números racionais de forma exata, sem perder precisão como acontece com floats. Se você fizer 1/3 no Python usando floats, vai dar 0.3333333333333333 e qualquer conta subsequente vai acumular erro. Com a classe Fraction, o resultado permanece como uma fração exata até o momento em que você decide converter. Isso muda completamente a forma como você trata divisões em pipelines de cálculo. Eu montei um sistema de precificação que envolvia porcentagens fragmentadas — cada produto tinha seu desconto aplicado em camadas successivas. Usar float me deu resultados inconsistentes, com centavos aparecendo e sumindo conforme a ordem das operações. Mudei para Fração e o problema desapareceu. A diferença entre uma implementação e outra foi de cerca de 4 horas de debugging para 30 minutos de ajuste.
Um detalhe que poucas pessoas mencionam: números racionais têm uma propriedade que parece óbvia mas causa confusão. Todo número racional tem uma representação decimal que ou é finita ou é periódica. Isso significa que 1/4 é 0.25 e para, enquanto 1/3 é 0.333... e o três se repete infinitamente. O oposto também vale: dízimas periódicas são racionais. A dízima 0.142857142857... com o ciclo 142857 repetindo é exatamente 1/7. Quando você vê um periódico longo, pode transformar de volta em fração multiplicando por potências de 10 e subtraindo. O processo é mecânico, mas funciona sempre.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Operações básicas e armadilhas comuns
Somar e subtrair exigem denominador comum. Multiplicar é direto: numerador com numerador, denominador com denominador. Dividir é multiplicar pelo inverso. O que mata gente é a simplificação. Se você não reduz a fração depois de cada operação, os números crescem rápido demais e o cálculo fica lento sem motivo. Eu um script que processava milhares de frações e estava levando 12 segundos pra rodar. Só de adicionar uma chamada pra simplify() da classe Fraction, caiu pra 0.8 segundos. O gcd (máximo divisor comum) por trás da simplificação evita que numeradores e denominadores fiquem absurdamente grandes. Outro ponto que todo mundo esquece: zero não pode estar no denominador. PARECE óbvio, mas em código Dinheiro aparece quando você calcula uma taxa e o resultado dá zero. Dividir por algo que era suposto ser o denominador zero faz o programa estourar. Sempre valide antes de operar.
Quando você precisa de uma representação decimal aproximada, converter fração pra float é seguro desde que você saiba que vai perder precisão. A conversão é direta: basta chamar float() no objeto Fraction. O contrário também funciona — converter decimal periódico em fração exige um pouco mais de lógica. Um exemplo prático: se você tem 2.666..., identifica o período (6), monta a equação x = 2.666... então 10x = 26.666... e subai: 9x = 24, logo x = 24/9 que simplificado vira 8/3.
Quando usar e quando fugir
Números racionais são ideais quando a precisão é crítica e os valores têm origem fracionária natural — divisões de receita, proporções geométricas, cálculos financeiros com juros fracionários. O problema é que nem todo sistema suporta frações nativamente. Bancos de dados tradicionais trabalham com DECIMAL ou FLOAT, e se você precisa armazenar resultados exatos de operações racionais, vai ter que fazer a conversão na mão ou usar uma biblioteca especializada. Se o seu projeto envolve muitos cálculos numéricos intensivos, frações podem ser um gargalo. Cada operação com Fração do Python é mais lenta que com float porque envolve_aritmética de inteiros arbitrariamente grandes. Para simulações científicas com milhões de iterações, float com tolerância de erro controlada costuma ser a escolha mais sensata. Use racionais quando a exatidão vale mais que performance, e floats quando o contrário for verdade.
Uma alternativa que não todo mundo conhece é o módulo decimal do Python. Ele oferece precisão fixa configurável e é mais rápido que Fração para certos casos, mas ainda assim não resolve o problema de representações periódicas. Decimal(1) / Decimal(3) vai te dar 0.3333333333333333333333333333 dependendo da precisão que você definir, e não uma fração exata. Sabe a diferença? Em contas financeiras onde o arredondamento precisa seguir regras específicas do bacen, decimal é a ferramenta certa. Em problemas de matemática pura onde 1/3 é sagrado e não pode ser aproximado, Fração é imbatível.