BigDecimal
BigDecimal é uma classe da API Java utilizada para representar números decimais com alta precisão, evitando problemas de arredondamento comuns nos tipos primitivos float e double.
Usamos BigDecimal principalmente quando o nosso modelo de negócio envolve valores financeiros, cálculos contábeis, monetários ou qualquer cenário onde precisão é obrigatória.
Exemplos de uso comuns:
- Valores monetários: salários, preços, juros;
- Cálculos financeiros: parcelas, impostos, descontos;
- Sistemas bancários e contábeis.
Não utilize double ou float para valores financeiros.
Os tipos double e float trabalham com aproximações binárias, o que pode gerar resultados inesperados, como:
System.out.println(0.1 + 0.2); // 0.30000000000000004
Com BigDecimal, esse problema não acontece.
Criando objetos BigDecimal
Como BigDecimal é uma classe, precisamos criar seus objetos explicitamente.
Forma correta (String)
BigDecimal valor = new BigDecimal("10.50");
Forma alternativa (valueOf)
BigDecimal valor = BigDecimal.valueOf(10.50);
Evite o construtor BigDecimal(double), pois ele herda o problema de precisão do double. ::
❌ Não recomendado:
BigDecimal valor = new BigDecimal(10.50);
Operações com BigDecimal
Diferente dos tipos primitivos, não usamos operadores matemáticos (+, -, *, /).
As operações são feitas através de métodos:
Soma
BigDecimal valor1 = new BigDecimal("10.00");
BigDecimal valor2 = new BigDecimal("5.50");
BigDecimal resultado = valor1.add(valor2);
System.out.println(resultado); // 15.50
Subtração
BigDecimal resultado = valor1.subtract(valor2);
Multiplicação
BigDecimal resultado = valor1.multiply(valor2);
Divisão
BigDecimal resultado = valor1.divide(valor2);
⚠️ Atenção: nem toda divisão gera um valor exato.
Arredondamentos com BigDecimal
Quando uma divisão gera dízima, é obrigatório informar escala e modo de arredondamento.
BigDecimal valor1 = new BigDecimal("10");
BigDecimal valor2 = new BigDecimal("3");
BigDecimal resultado = valor1.divide(valor2, 2, RoundingMode.HALF_UP);
System.out.println(resultado); // 3.33
Principais modos de arredondamento
HALF_UP→ arredonda para cima quando ≥ 5 (mais comum em finanças)HALF_DOWN→ arredonda para baixo quando = 5HALF_EVEN→ arredondamento bancárioDOWN→ sempre truncaUP→ sempre arredonda para cima
Comparação de valores
Para comparar BigDecimal, não use equals em regras de negócio.
BigDecimal a = new BigDecimal("10.0");
BigDecimal b = new BigDecimal("10.00");
a.equals(b); // false
Use compareTo:
a.compareTo(b); // 0 (valores iguais)
Resultado do compareTo:
0→ iguais-1→ menor1→ maior
Boas práticas ao usar BigDecimal
- Sempre prefira String ou valueOf no construtor;
- Nunca use operadores matemáticos (
+,-,*,/); - Defina explicitamente escala e arredondamento em divisões;
- Use
compareTopara comparações; - Trate
BigDecimalcomo imutável (cada operação gera um novo objeto).
Exemplo 1
Simulação de cálculo de abastecimento de gasolina
Regras do cenário
- O valor do litro possui 3 dígitos decimais (ex: 5.879)
- A quantidade de litros pode ser decimal
- O valor final deve ser arredondado para 2 casas decimais
- Arredondamento financeiro (HALF_EVEN)
import java.math.BigDecimal;
import java.math.RoundingMode;
public class PostoCombustivel {
public static void main(String[] args) {
BigDecimal precoLitro = new BigDecimal("5.879");
BigDecimal abastecimento1 = calcularValorCombustivel(precoLitro, new BigDecimal("10"));
BigDecimal abastecimento2 = calcularValorCombustivel(precoLitro, new BigDecimal("23.45"));
BigDecimal abastecimento3 = calcularValorCombustivel(precoLitro, new BigDecimal("42.7"));
System.out.println("Abastecimento 1: R$ " + abastecimento1);
System.out.println("Abastecimento 2: R$ " + abastecimento2);
System.out.println("Abastecimento 3: R$ " + abastecimento3);
}
/**
* Calcula o valor total do abastecimento
*
* @param valorLitro valor do litro do combustível (3 casas decimais)
* @param quantidadeLitros quantidade abastecida
* @return valor total a pagar (2 casas decimais)
*/
public static BigDecimal calcularValorCombustivel(BigDecimal valorLitro,
BigDecimal quantidadeLitros) {
BigDecimal valorTotal = valorLitro.multiply(quantidadeLitros);
return valorTotal.setScale(2, RoundingMode.HALF_UP);
}
}
Exemplo 2
Exemplo simples de cálculo de parcela (didático)
- Valor total com 2 casas decimais
- Cada parcela com 2 casas decimais
- Arredondamento explícito
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Parcelamento {
public static void main(String[] args) {
BigDecimal valorTotal = new BigDecimal("100.00");
int quantidadeParcelas = 6;
BigDecimal valorParcela = calcularValorParcela(valorTotal, quantidadeParcelas);
System.out.println("Valor da parcela: R$ " + valorParcela);
}
public static BigDecimal calcularValorParcela(BigDecimal valorTotal,
int quantidadeParcelas) {
return valorTotal.divide(
BigDecimal.valueOf(quantidadeParcelas),
2,
RoundingMode.HALF_EVEN
);
}
}