O erro de arredondamento não é aleatório e, da maneira como é implementado, tenta minimizar o erro. Isso significa que, às vezes, o erro não é visível ou não há erro.
Por exemplo, 0.1
não é exatamente 0.1
ou seja, new BigDecimal("0.1") < new BigDecimal(0.1)
mas0.5
é, é exatamente1.0/2
Este programa mostra os verdadeiros valores envolvidos.
BigDecimal _0_1 = new BigDecimal(0.1);
BigDecimal x = _0_1;
for(int i = 1; i <= 10; i ++) {
System.out.println(i+" x 0.1 is "+x+", as double "+x.doubleValue());
x = x.add(_0_1);
}
impressões
0.1000000000000000055511151231257827021181583404541015625, as double 0.1
0.2000000000000000111022302462515654042363166809082031250, as double 0.2
0.3000000000000000166533453693773481063544750213623046875, as double 0.30000000000000004
0.4000000000000000222044604925031308084726333618164062500, as double 0.4
0.5000000000000000277555756156289135105907917022705078125, as double 0.5
0.6000000000000000333066907387546962127089500427246093750, as double 0.6000000000000001
0.7000000000000000388578058618804789148271083831787109375, as double 0.7000000000000001
0.8000000000000000444089209850062616169452667236328125000, as double 0.8
0.9000000000000000499600361081320443190634250640869140625, as double 0.9
1.0000000000000000555111512312578270211815834045410156250, as double 1.0
Nota: isso 0.3
está um pouco desligado, mas quando você chega aos 0.4
bits, precisa mudar um para baixo para se ajustar ao limite de 53 bits e o erro é descartado. Mais uma vez, um erro volta a aparecer0.6
e 0.7
mas para 0.8
a 1.0
que o erro é descartado.
Adicioná-lo 5 vezes deve acumular o erro, não cancelá-lo.
A razão pela qual há um erro é devido à precisão limitada. ou seja, 53 bits. Isso significa que, à medida que o número usa mais bits à medida que aumenta, os bits precisam ser descartados no final. Isso causa arredondamentos, que neste caso estão a seu favor.
Você pode obter o efeito oposto ao obter um número menor, por exemplo, 0.1-0.0999
=>1.0000000000000286E-4
e vê mais erros do que antes.
Um exemplo disso é o porquê no Java 6 Por que Math.round (0.49999999999999994) retorna 1 Nesse caso, a perda de um bit no cálculo resulta em uma grande diferença para a resposta.