Problema com float e double:
- Projetados para cálculos científicos e matemáticos, executam aritmética binária de ponto flutuante.
- Não são adequados para cálculos monetários ou situações que exigem respostas exatas.
- Não conseguem representar com precisão potências negativas de dez, como 0.1, o que leva a erros.
Exemplo 1:
Cálculo incorreto ao subtrair valores em dólares:
System.out.println(1.03 - 0.42); // Resultado: 0.6100000000000001
Exemplo 2:
Erro ao comprar nove itens de 10 centavos cada:
System.out.println(1.00 - 9 * 0.10); // Resultado: 0.09999999999999998
Mesmo arredondando, os erros persistem.
Problema com cálculos progressivos, como ao comprar doces a preços incrementais de 0.10 a 1.00.
Exemplo 3:
Erro ao comprar doces até não ter mais dinheiro:
double funds = 1.00;
for (double price = 0.10; funds >= price; price += 0.10) {
funds -= price;
}
System.out.println(funds); // Resultado: 0.3999999999999999
Solução 1: Usar BigDecimal
- Ideal para cálculos financeiros e situações em que precisão é fundamental.
- Evitar o uso do construtor double de BigDecimal, preferindo o construtor String.
Exemplo com BigDecimal:
BigDecimal funds = new BigDecimal("1.00");
BigDecimal price = new BigDecimal("0.10");
int itemsBought = 0;
while (funds.compareTo(price) >= 0) {
funds = funds.subtract(price);
price = price.add(new BigDecimal("0.10"));
itemsBought++;
}
System.out.println(itemsBought + " items bought. Money left: " + funds);
// Resultado: 4 items bought. Money left: 0.00
O cálculo agora é preciso.
Desvantagens de BigDecimal:
- Menos conveniente de usar do que os tipos primitivos.
- Mais lento, especialmente para grandes volumes de operações.
Solução 2: Usar int ou long
- Para evitar os problemas de precisão, faça cálculos em centavos, usando int ou long em vez de dólares com double.
Exemplo com int (em centavos):
int funds = 100; // 1.00 dólar = 100 centavos
int price = 10; // 0.10 dólar = 10 centavos
int itemsBought = 0;
while (funds >= price) {
funds -= price;
price += 10;
itemsBought++;
}
System.out.println(itemsBought + " items bought. Money left: " + funds);
// Resultado: 4 items bought. Money left: 0
O cálculo é rápido e preciso.
Conclusão:
- Não use float ou double para cálculos que exigem precisão exata.
- Use BigDecimal para cálculos monetários ou situações que exigem precisão decimal.
- Use int ou long para cálculos financeiros que não envolvam grandes números, fazendo os cálculos em centavos.
Escolhas:
- Para até 9 dígitos, use int.
- Para até 18 dígitos, use long.
- Para quantidades maiores, use BigDecimal.
- Este resumo mostra que, dependendo do contexto, a escolha entre BigDecimal, int ou long pode otimizar tanto a precisão quanto o desempenho.
Top comments (0)