Multiplicação com double

Eu estava fazendo um exercício com for loop e tinha a unidade de pão = 1,80 e eu precisava fazer uma tabela de preço até 50 pães.
Mas o problema aconteceu quando multiplicou por 5.
1,8 x 5 = 9. Mas o programa indicou 8,99999999…
Por que?
(Usei Double)

Mas como eu resolvo isso?

Mostras o valor com o numero de casas decimais que pretendes, com printf ou DecimalFormat:

    double value = 8.99999999;

    System.out.printf("%.3f\n", value); // %.3f - três casas decimais
    System.out.println(new DecimalFormat("0.00").format(value));  // 0.00 - Exatamente duas casas decimais
    System.out.println(new DecimalFormat("0.##").format(value));  // 0.## - No máximo duas casas decimais

Isso acontece porque float/double são implementados de acordo com a norma IEEE 754, que naturalmente possui uma imprecisão nas casas decimais. A explicação completa está aqui.

Então dependendo de como você faz as contas, isso pode ou não resultar em valores imprecisos. Por exemplo, se usar direto System.out.println(1.8 * 5);, ele imprime 9.0

Se quer precisão, o jeito é não usar double/float, e em vez disso usar java.math.BigDecimal. Você terá mais precisão, sob o custo do código ficar mais “chato” de se lidar. Como você não colocou seu código, segue um exemplo, só para vermos a diferença (coloquei alguns valores que propositalmente geram o problema da imprecisão - não é exatamente o mesmo valor do seu caso, mas a ideia é a mesma):

double d = (0.1 + 0.2) * 6;
System.out.println(d); // 1.8000000000000003
System.out.println(d * 5); // 9.000000000000002

BigDecimal bd = new BigDecimal(d, new MathContext(2, RoundingMode.DOWN));
System.out.println(bd); // 1.8
System.out.println(bd.multiply(new BigDecimal(5))); // 9.0

Na verdade o problema com o double é a exatidão do número, não a precisão.
Por exemplo: (0.1 + 0.2) * 6 = 1.8000000000000003 é um resultado bastante preciso, tem 16 casas decimais, entretanto é um resultado inexato, deveria ser 1.8000000000000000, ou simplesmente 1,8.

Há alguns anos precisei desenvolver um sistema de análise de qualidade da água para um núcleo ambiental do SENAI. A qualidade da água é mensurada através do IQA que é o produto ponderado do resultados de 9 parâmetros distintos (Mais informações aqui: http://pnqa.ana.gov.br/indicadores-indice-aguas.aspx).

Calcular esses 9 parâmetros com double, Double ou BigDecimal se mostrou inviável pois devido ao problemas de inexatidão, os resultados estavam errados.

Para mim a solução foi usar a biblioteca JScience, ela dispões de tipos numéricos muito mais performáticos que o BigDecimal e permite configurar a precisão e exatidão dos valores, eliminando o problema do padrão IEEE 754.