Vou explicar uma coisa meio chata, mas que todo mundo deveria saber.
Em Java, C, C#, VB.NET, VB 6, C++, Fortran, Pascal/Delphi, etc., costuma haver dois tipos de dados de ponto-flutuante, chamados normalmente de “float” e “double”. (No VB são “single” e “double” e no Fortran, se não me engano, são “real” e “double precision”).
Como eles são implementados por hardware e seguem um determinado padrão (IEEE-754, normalmente uma mesma conta tem de dar resultados iguais em todas essas linguagens. TODAS. (OK, cada uma dessas linguagens usa um modo diferente de acertar alguns parâmetros no processador que na prática irão dar resultados ligeiramente diferentes - modos de arredondamento, comportamento quanto a divisão por zero e outras sutilezas previstas no padrão. Mas na prática deveriam dar o mesmo resultado).
Só que o Java imprime os números, por default, com o máximo possível de algarismos depois da vírgula - não só 6, como em C. Então isso é que provoca mostrar esses números esquisitos como “533.[telefone removido]” ou coisas parecidas.
Na verdade, esse número foi a mesma coisa que um programa equivalente em C calcularia. Mas como em C só mostramos 6 casas depois da vírgula, por default, então você tem um número “533.300000” e você acha que ele fez as contas exatamente. Em outras linguagens (como Pascal/Delphi) há uma limitação parecida.
Se você não sabe lidar direito com esses números quebrados (ou arredondando, ou tomando outras providências), então use um tipo decimal (como o System.Decimal do C# ou o java.math.BigDecimal do Java). Para fazer contas de dinheiro, por exemplo, você tem de tomar bastante cuidado com double, já que você pode ter tal tipo de surpresas.