Problema com arrendondamento

Estou com um problema de arrendondamento, o código é o seguinte:
public class Arred {
public static void main(String[] args){
double vlrTotal = 0;
double vlrDesconto = 0.80;
double vlrSubttl = 2.80;
int tipo = 0;

    if(tipo == 0){
    vlrTotal  = vlrSubttl - vlrDesconto;
    }else{
    vlrTotal  = vlrSubttl - (vlrSubttl * vlrDesconto);
    }
    System.out.println(" vlrDesconto = "+ vlrDesconto +"   vlrSubttl = "+ vlrSubttl +"         vlrTotal = " + vlrTotal);

}

}

O resultado esta saindo assim:
vlrDesconto = 0.8 vlrSubttl = 2.8 vlrTotal = 1.9999999999999998

Como era para sair:
vlrDesconto = 0.8 vlrSubttl = 2.8 vlrTotal = 2.00

se alguém poder ajudar ficarem muito grato!

Isso aí é um problema por causa do tipo Double que você está usando… tem alguns valores que são simplesmente impossíveis de representar com double, daí acaba se usando um valor aproximado.
Tente por exemplo executar a soma: 0.1 + 0.1 + 0.1

O conselho geral é: não utilize double para lidar com dinheiro.
Alternativas:

  • Use BigDecimal, usando o construtor de String, que mantém a precisão de entrada
  • Utilize uma biblioteca específica que tenha o tipo Dinheiro (Money): se for uma aplicação séria
  • Utilize int/long mas para contar a menor unidade daquela moeda (no seu caso centavos).

Com long ficaria assim:

long desconto = 80;
long subtotal = 280;
long total = // sua conta aqui;
1 curtida

Gosto bastante da API JScience para trabalhar com números.
Ela possui configurações de precisão e exatidão e suas classes são mais rápidas que BigInteger ou BigDecimal.