Façam o teste ai:
System.out.println(614.9 * 100);
System.out.println(614.8 * 100);
System.out.println(614.7 * 100);
System.out.println(614.6 * 100);
A saída:
Se eu alterar de double para float, os valores que estavam certos ficam errados e os que estavam errados ficam certos o.O
Com BigDecimal o erro é parecido com o caso do double, mas com mais casas decimais.
Alguem sabe o porque disso? E qual seria o melhor jeito de resolver?
Muito Bom!
Já imaginava que era erro de arredondamento mas não sabia o porquê.
Em .Net tem o tipo Decimal , existe também em Java, ou algo equivalente?
Existe no Java o java.math.BigDecimal, mas ele é bem mais desajeitado de usar que o System.Decimal (ou decimal no C#).
Entretanto, o java.math.BigDecimal pode trabalhar com precisão indeterminada, o que não ocorre com o System.Decimal, que trabalha com um valor de apenas 128 bits.
Eu, em particular, acho falta de algo que seja semelhante ao System.Decimal, e que seja fácil de usar. É um porre quando você tem de fazer:
BigDecimal bd1= new BigDecimal ("1.0");
BigDecimal bd3 = new BigDecimal ("3.0");
BigDecimal bd13 = bd1.divide (bd3, 20, BigDecimal.ROUND_HALF_EVEN);
em vez de (se não me engano - não trabalho 100% do tempo com C#)
decimal bd13 = 1.0M / 3.0M;
só para achar o valor de 1/3.
… e depois o pessoal da Sun diz que sobrecarga de operadores não faz falta.
O BigDecimal e BigInteger poderiam se comportar praticamente como seus respectivos tipos primitivos. Lists e maps poderiam ter a sintaxe de arrays primitivos.
Classes como vetores matemáticos poderiam se beneficiar em grande escala… entre outras coisas.