Problemas Com Numeros Decimais - Problemas Com Números Decimais 5 Ano – SRYSF
Problemas Com Números Decimais 5 Ano – SRYSF

O que acontece quando os decimais não batem certo

Quase todo mundo que já lidou com planilhas ou sistemas financeiros já encontrou esse problema. O valor que deveria ser 19,90 aparece como 19,899999999. O relatório fecha errado. O caixa não fecha. A coisa mais simples do mundo vira dor de cabeça se você não souber como funciona por baixo dos panos.

por que os problemas com numeros decimais acontecem

A maior parte dos computadores armazena números em binário. E 0,1 em decimal não tem representação exata em binário. É como tentar dividir uma pizza em três partes iguais usando só pedaços que são metade, quarto, oitavo. Você nunca chega no terço exato. O computador faz o melhor que pode e guarda uma aproximação. Quando você soma várias dessas aproximações, o erro se acumula e aparece na última casa decimal. Isso não é um bug. É a forma como o padrão IEEE 754 funciona desde os anos 80. As linguagens que usam float ou double herdam esse comportamento. JavaScript, Python, Java, C, todas. Se você ver um número decimal sendo armazenado como ponto flutuante, problemas vão aparecer eventualmente. Só falta o momento certo.

Eu lembro de um caso específico que tive anos atrás. Estava trabalhando em um sistema de estoque onde o fornecedor enviava os preços em centavos com duas casas decimais. O programa somava tudo e sempre dava diferença de 0,01 ou 0,03 no total. Gastei três dias rastreando sem encontrar nada. No final, descobri que era a soma acumulada de dezenas de valores float. A solução foi converter tudo para inteirosando os centavos. Preço 19,90 virou 1990. Soma inteira. Resultado perfeito. Voltei a representar como moeda só na hora de exibir na tela.

como resolver na prática

A primeira coisa que todo mundo deveria fazer é entender qual tipo de dado está usando. Se o seu código usa float ou double para valores monetários, está inevitavelmente sujeito a erros de arredondamento. A correção imediata é usar uma representação decimal exata. Na maioria das linguagens modernas isso já existe nativamente ou via biblioteca. Em JavaScript, o pacote decimal.js é o mais usado. Em Python, o módulo decimal vem instalado na biblioteca padrão. Em Java, a classe BigDecimal resolve. Em C#, existe o tipo decimal nativo. Em PHP, você pode usar o pacote bcmath ou bibliotecas como brick/math. A regra geral é: nunca use ponto flutuante para dinheiro, para porcentagens ou para qualquer coisa onde um erro de 0,01 seja inaceitável.

Outro ponto que as pessoas ignoram é o arredondamento. Mesmo usando uma representação decimal correta, você precisa decidir como arredondar. O padrão comercial mais comum é o arredondamento para o vizinho par (round half to even), mas muitos sistemas usam o clássico arredondamento para cima em .5. Se você está processando pagamentos, consulte a regulamentação local. O Brasil usa a tabela do Banco Central, que define regras específicas de arredondamento para operações financeiras. Se o seu sistema já está em produção com floats e você não pode refazer toda a base de dados de uma vez, existe uma saída intermediária. Multiplique todos os valores por 100, 1000 ou 10000 dependendo da precisão que você precisa, trabalhe com inteiros e divida só na exibição. Eu fiz isso em um projeto onde a migração para BigDecimal levaria semanas. A solução com inteiros ficou pronta em dois dias e eliminou todos os erros de soma.

👉 Clique no botão abaixo para saber mais sobre o assunto!

erros comuns que você provavelmente já cometeu

A conversão de string para decimal é um armadilha frequente. Em JavaScript, Number("19,90") retorna NaN porque a vírgula não é separador decimal no padrão japonês. O correto é substituir a vírgula por ponto antes de converter, ou usar uma biblioteca de parsing. O mesmo vale para entrada de usuário: se o campo aceita vírgula como separador decimal, você precisa normalizar antes de processar. Outro erro comum é confiar em toFixed() para arredondamento. Em JavaScript, toFixed volta uma string, não um número, e o comportamento de arredondamento varia entre motores. O que funciona no Chrome pode dar resultado diferente no Safari. Se você precisa de precisão, use round com uma lógica explícita, não métodos prontos de formatação.

Quem trabalha com banco de dados também precisa prestar atenção. O tipo DECIMAL ou NUMERIC no PostgreSQL, MySQL e SQL Server armazena valores exatos. Já FLOAT e REAL são aproximações. Se sua tabela usa float para colunas de preço, nenhuma correção no código vai resolver o problema raiz. Você precisa migrar o tipo da coluna.

quando o problema não é o tipo de dado

Às vezes você usa BigDecimal, decimais exatos, e ainda assim o resultado não bate. Aí o problema pode estar em outro lugar. Conversões implícitas entre tipos são um culprit frequente. Um BigDecimal multiplicado por um double resulta em double. Uma operação mista entre tipos decimais de bibliotecas diferentes pode perder precisão se uma delas for convertida para float no meio do caminho. Também é comum ver gente usando redondez em etapas intermediárias de um cálculo longo. Cada vez que você arredonda um valor no meio do processo, você introduz um erro que vai se propagar. O ideal é manter a precisão máxima durante todo o cálculo e arredondar só no resultado final. Eu vi um relatório mensal que fechava 200 reais errado porque cada linha individual era arredondada antes da soma total. Quando mudei para arredondar só no total, a diferença sumiu.

Se você está lidando com taxas de juros compostas ou cálculos financeiros complexos, tenha cuidado com a convenção de dia fracionário. Existem várias formas de calcular juros entre datas (30/360, actual/365, actual/actual). Escolher a errada é um erro que não gera exceção, só um resultado silenciosamente incorreto. Isso acontece muito em sistemas legados que herdam regras de cálculo de terceiros.

dica prática de depuração

Quando o número decimal tá errado e você não consegue achar o motivo, a melhor primeira passo é parar de confiar na impressão na tela. Valores como 19,90 podem ser impressos normalmente mas armazenar 19,89999999999999857. Use log de debug com precisão máxima para ver o valor real na memória. Em Python, repr() mostra a representação completa. Em JavaScript, number.toPrecision(17) revela o que realmente está armazenado. O que você vê formatado nem sempre é o que o computador está calculando. Se o problema é em larga escala, como uma conta de produção inteira com valores errados, considere escrever um script de validação que recompare todos os valores armazenados contra uma referência calculada de outra forma. No meu caso do estoque, eu gerei uma versão dos mesmos dados usando inteiros e comparei linha por linha com a versão em float. O script levou 4 minutos para rodar e apontou exatamente quais transações tinham divergência. Sem ele, eu estaria gastando dias inspecionando manualmente.

O resumão é simples: entenda o tipo de dado que seu sistema usa, troque float por decimal exato onde for monetário ou de precisão crítica, arredonde só no final, e valide com logs de precisão máxima antes de acreditar que o problema foi resolvido. Decimais parecem coisas simples mas escondem armadilhas que só aparecem depois que o sistema já tá no ar.