3
respostas

Erro - Formato de saída do Double

public class TesteFuncionario {

    public static void main(String[] args) {

        Funcionario nico = new Funcionario();
        nico.setNome("Nico Steppat");
        nico.setCPF("223355646-91");
        nico.setSalario(2600.80);

        System.out.println(nico.getNome());
        System.out.println(nico.getBonificacao());

    }

}

Boa tarde, senhores! Ao executar o código acima da classe "TesteFuncionario.java", tenho as seguintes saídas:

Nico Steppat 260.08000000000004

No programa rodado pelo Nico, temos apenas 2 decimais. O que fiz errado, ou qual ajuste devo fazer?

3 respostas

Boa tarde, Rogério! Como vai?

Na realidade, a impressão ocorreu com apenas uma casa decimal como é visto a partir de 14:37 dessa aula. Essa diferença ocorreu devido ao valor diferente que vc colocou para o salário. Enquanto o Nico colocou 2600 vc colocou 2600.80 gerando assim a diferença na saída.

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!

Você não fez nada de errado mano.

Você pode formatar a saída do console dessa forma:

System.out.printf("%.2f",nico.getBonificacao());

Ou assim também:

System.out.println(String.format("%.2f",nico.getBonificacao()));

Olá Rogério.

Muito boa tua observação. A resposta é um pouco complexa:

Esse erro ocorre devido a um problema de representação de números de ponto flutuante em binário. A multiplicação dos números 2600.80 * 0,1 gera, em Binário, uma dízima periódica e quando é arredondada para caber nos 64 bits, leva a um erro de precisão na última casa: 260.08000000000004. Isso ocorre com quase todas as linguagens de programação que, assim como o Java, seguem o padrão IEEE 754.

Esse mesmo problema ocorre quando você faz a seguinte soma: 0,1 + 0,2. Obviamente o resultado é 0,3. Mas quando você executa

double x = 0.1;
double y = 0.2;
double z = x + y;
System.out.println(z);

O resultado é 0.30000000000000004. Se você colocar o número 0,1 em uma calculadora científica e pedir pra ela converter para binário, ela apresentará a seguinte dízima periódica:

0,1 = 0,0001100110011001100110011001100110011001100110011...

Devido a esse arredondamento, aparece essa "sujeira" no double. A solução é formatar como o Thiago Rasquino sugeriu acima ou usar BigDecimal que é uma classe especializada em trabalhar com números de alta precisão.

No vídeo não apareceu esse erro porque, como disse Gabriel Leite, o instrutor usou 2600 e não 2600.80.

Dá uma olhada nesse interessante site : https://0.30000000000000004.com

Curiosamente esse problema não ocorre com o float embora tenha menos precisão. É que o float usa uns bits a mais internamente e depois faz um arredondamento.

O assunto é meio complicado, mas espero que tenha sacado um pouco a ideia. :)

Obs: No curso Java parte 4 - Aula 5 - Capitulo 04 (Sacando com Unchecked Exception) em 12:52 o professor Nico Steppat se depara com exatamente esse problema.