Java multiplicando errado

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?

erros de arredondamento do float

veja o doc abaixo

http://docs.sun.com/source/806-3568/ncg_goldberg.html

O problema não está no Java, mas na base binária. Dá uma lida aqui:
http://www.guj.com.br/posts/list/68086.java#357907

E aqui:
http://www.guj.com.br/posts/list/84121.java#448928

Muito Bom!

Já imaginava que era erro de arredondamento mas não sabia o porquê.

tenso

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.