Trabalhando com contas que têm casas decimais no dia a dia
Eu já passei por problemas sérios com isso quando estava configurando um sistema de faturamento para uma clínica médica. O problema era que os valores dos procedimentos vinham com até três casas decimais no banco de dados, mas a tabela de preços do convênio só aceitava dois dígitos. Isso gerava divergência de R$ 0,03 em cada conta, e ao final do mês a diferença acumulada chegava a R$ 47,00. A solução foi criar uma regra de arredondamento que considerasse o valor total da fatura, não linha por linha. Arredondar na linha individual gera erro cumulativo que ninguém nota até o fechamento.
Contas com numeros decimais: como evitar perda de dinheiro
O básico é simples de entender mas fácil de errar na prática. Quando você trabalha com valores monetários, precisa decidir desde o início se vai usar tipo decimal, float ou string formatada. Tipo float parece conveniente porque aceita qualquer valor, mas internamente ele usa representação binária que causa erros de precisão. Um valor como 0,1 não existe exatamente em binário, então às vezes aparece 0,10000000000000001. Em contas simples isso não importa, mas quando soma centenas de lançamentos o erro se multiplica. Tipo decimal é diferente. Ele armazena o valor exato que você digitou, sem aproximação. A desvantagem é que operações matemáticas ficam mais lentas, principalmente se você está fazendo cálculos financeiros em tempo real com milhares de registros. No nosso caso de faturamento hospitalar, a diferença de performance foi irrelevante porque o volume era de umas duzentas contas por dia. Gostamos de decimal para valores monetários porque a precisão vale mais que a velocidade.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Uma coisa que muitos programadores esquecem é o comportamento do arredondamento. O padrão do Python, por exemplo, usa round half to even, que arredonda para o par mais próximo quando o valor está exatamente no meio. Isso significa que 2,5 vira 2 e 3,5 vira 4. Pode parecer estranho no começo, mas é matematicamente correto porque evita viés sistemático. Já vi sistemas de contabilidade que usavam arredondamento para cima em todos os casos, o que gerava um acúmulo de centavos a favor da empresa em favor do cliente. A longo prazo faz diferença. Outro problema prático é a exibição dos valores. Você pode ter um cálculo que resulta em 150,45600000001 por causa de operações anteriores com float. Se mostrar esse valor na tela fica estranho. A solução é usar formatação de saída com duas casas decimais, mas manter o valor original para novos cálculos. Formatar antes de calcular muda o resultado final e isso ninguém percebe até o extrato bater errado.
Se você está começando agora com contas que precisam de precisão, recomendo usar biblioteca decimal do Python diretamente. Ela já implementa as regras de arredondamento corretas e evita_surpresa. Definir a precisão no contexto inicial é melhor que tentar ajustar depois. O overhead de performance geralmente não compensa a economia de código, a menos que você esteja processando milhões de transações por segundo. Cenários onde essa abordagem falha completamente são sistemas legados que foram migrados de planilha para banco de dados. As planilhas usam representação binária interna e aceitam qualquer número, então valores que pareciam corretos na interface na verdade eram aproximações. Quando você importa esses dados para um sistema com decimal estrito, aparece inconsistência de valores que ninguém entendia antes. A solução geralmente é refazer todo o histórico com valores arredondados manualmente, o que leva umas três semanas para um sistema médio.
Um detalhe importante sobre moedas diferentes. Real, dólar, euro têm comportamentos distintos em relação a casas decimais. O real aceita dois dígitos após a vírgula na maioria das transações, mas alguns convênios médicos usam três para procedimentos especializados. O dólar americano também usa dois dígitos, mas o iene japonês não usa nenhuma casa decimal. Se seu sistema precisa suportar moedas múltiplas, defina a precisão por tipo de moeda desde o início. Tentar padronizar depois gera correções caras em produção.