Você está na página 1de 3

Por que prefervel utilizar BigDecimal

a double.
Para descontrair um pouco, vou colocar aqui um artigo onde descrevo minha predileo ao uso
do BigDecimal ao uso da primitiva double ou de seu wrapper Double.
O texto baseado num post que coloquei no forum da equipe que trabalho numa resposta que
postei no GUJ.

Por que prefervel utilizar BigDecimal a double (ou seu wrapper Double).
O double utiliza regras de ponto flutuante que, computacionalmente, implicam em gerar (o que
chamo de) sugeira, especialmente aps manipulaes matemticas.
Um exemplo disso :
1 double sum = 0.1 + 0.2;
2 System.out.println(sum);
O resultado ser diferente de 0.3 contendo valores discretos na ordem de 110^-16
acrescentados ao valor.
Para evitar-se isso, podemos utilizar o BigDecimal Seu controle no utiliza pontos flutuantes
tornando-o mais seguro para clculos.
Sendo assim, prefirvel trabalhar diretamente com BigDecimal e Strings a me arriscar em
manipulaes com double (salvo alguma exceo muito convincente).
Abaixo segue exemplo de manipulao de doubles em comparao com BigDecimal utilizandose de NumberFormat.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

double d = 1.0/3.0;
double d2 = 0.3333333333333333333333333333333333333333333333333333333;
BigDecimal bd = BigDecimal.valueOf(d);
BigDecimal bd2 = BigDecimal.valueOf(d2);
BigDecimal bdS = new
BigDecimal("0.3333333333333333333333333333333333333333333333333333333");
System.out.println("Imprimindo double");
System.out.println(d);
System.out.println(d2);
System.out.println("Imprimindo BigDecimal");
System.out.println(bd);
System.out.println(bd2);
System.out.println(bdS);

17
18
19
20
21
22
23
24
25
26
27

DecimalFormat f = new
DecimalFormat("0.0000000000000000000000000000000000000000000000000000000");
System.out.println("Imprimindo double atravs de um Format");
System.out.println(f.format(d));
System.out.println(f.format(d2));
System.out.println("Imprimindo BigDecimal atravs de um Format");
System.out.println(f.format(bd));
System.out.println(f.format(bd2));
System.out.println(f.format(bdS));

O nico resultado que satisfez o que era esperado foram os System.out da varivel bdS.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Imprimindo double
0.3333333333333333
0.3333333333333333
Imprimindo BigDecimal
0.3333333333333333
0.3333333333333333
0.3333333333333333333333333333333333333333333333333333333
Imprimindo double atravs de um Format
0,3333333333333333000000000000000000000000000000000000000
0,3333333333333333000000000000000000000000000000000000000
Imprimindo BigDecimal atravs de um Format
0,3333333333333333000000000000000000000000000000000000000
0,3333333333333333000000000000000000000000000000000000000
0,3333333333333333333333333333333333333333333333333333333

Outro exemplo:

1
2
3
4
5
6
7
8
9

double d = 4.0/9.0;
double d2 = 0.4444444444444444449444444444444444444444444444444444444;
//
^
BigDecimal bd = BigDecimal.valueOf(d);
BigDecimal bd2 = BigDecimal.valueOf(d2);
System.out.println(d == d2);
System.out.println(bd == bd2);
System.out.println(bd.equals(bd2));

Percebe que tem um 9 no meio dos 4?, a sada resultante foi:

1
2
3

true //Eles so iguais?????


false //Certo. Estou comparando objetos diferentes.
true //Eles so iguais?????

So detalhes como esse que foram a evitar o double O BigDecimal TAMBM no


perfeito, mas acho que ele mais adequado quando se trabalha com casas decimais.
Assim que possvel, colocarei mais exemplos comparativos entre double e BigDecimal.

Você também pode gostar