Bug no meu arredondamento de valores

Bom dia galera, blz ?

to com a seguinte duvida…preciso fazer um método de arredondamento ( coisa simples )

fiz assim:

public static double arredonda(double num, int casas) {
num = num * (Math.pow(10d, casas));
long num2 = Math.round(num);
num = num2 / (Math.pow(10d, casas));
return num;
}

só que começou acontecer um erro estranho…quando eu passo esse valores? num=0.0005 e casas=3 ele retorna o seguinte valor: 0.0010 …TEM UM ZERO PERDIDO AI NO MEIO.

para tentar arrumar esse erro fiz o seguinte:

public static double arredonda(double num, int casas) {
num = num * (Math.pow(10d, casas));
long num2 = Math.round(num);
num = num2 / (Math.pow(10d, casas));
Double numArre = num;
if (numArre.toString().substring(numArre.toString().indexOf(".")).length()>(casas+1)){
//numArre=Double.parseDouble(numArre.toString().substring(0, numArre.toString().length()-1));
//ou
String arrendondaString = numArre.toString().substring(0, numArre.toString().length()-1);
numArre=Double.valueOf(arrendondaString);
num=numArre.doubleValue();
}
return num;
}

entrei com os mesmo valores (num=0.0005 e casas=3) CONTINUOU DANDO O MESMO RESULTADO: 0.0010

ai resolvi mudar tudo…fiz o seguinte:

public static double arredonda(double num, int casas) {
BigDecimal bd = new BigDecimal(num);
bd = bd.setScale(casas,BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}

entrei com os mesmo valores (num=0.0005 e casas=3) CONTINUOU DANDO O MESMO RESULTADO: 0.0010

O que ta acontecendo ? EU QUERO QUE O RESULTADO SEJA 0.001 ( É PARA RELATORIOS) !!! PORQUE TA SAINDO ESSE RESULTADO: 0.0010 ??? PODE SER BUG DO JAVA ?

obs: tentai mais metodo diferente para resolver isso mas tb deu o mesmo erro.

valeu galera !!!

Você poderia fazer o seguinte:

String formatado = new DecimalFormat("0.###").format(valor);

Preciso retornar um double;

Uai, mas é esse mesmo o valor esperado. O número 0.0010 é exatamente o mesmo que 0.001.

Ou sua professora de matemática faltou a todas as aulas que ela ia lhe dar?

o bezier curve…POR FAVOR…leia tudo o que eu escrevi !!!

return Double.parseDouble(new DecimalFormat("0.###").format(valor)); 

O que o bezier disse é que a função está retornando o valor correto, ou seja, 0,0010.
Esse é o papel dela, fazer o arredondamento.

Quem está colocando aquele 0 ali é a máscara que você usou no relatório, na hora de exibir o dado.
Verifique a função que gera o relatório, pois é ela quem está formatando a saída desse jeito.

Ah, e sempre que postar código, ponha ele entre as tags code:

   //Seu código aqui

Isso fará com que o código fique formatado.

Tente desse jeito!

Resultado volta sem o zero que tu nao quer!

Double valor = 0.00010; String formatado; Double valorFormatado = Double.parseDouble(formatado = new DecimalFormat("#.####").format(valor).replace(',', '.'));

Eu entendi perfeitamente. Quando você converte um double para uma String, usando a conversão padrão do Java, ele mostra um zero a mais na direita do número às vezes. O jeito correto de lidar com isso é formatar corretamente o número na saída.

class TesteDecimal {
    public static void main (String[] args) {
        double d = 0.001; // note que isto não é um valor exato em binário!
        System.out.println (d); // imprime "0.0010"
        double[] valores = {
            0,
            0.1,
            0.01,
            0.001,
            0.0001,
            0.00001,
            0.000001
        };
        // O código a seguir imprime:
        // 0.0
        // 0.1
        // 0.01
        // 0.0010
        // 1.0E-4
        // 1.0E-5
        // 1.0E-6
        for (int i = 0; i < valores.length; ++i) {
           System.out.println (valores[i]);
        }
    }
}

Você porventura acha que 0.0 não é o mesmo número que zero?

Não entendi. Se é para um relatório, por que você precisa de um double? Você não vai apenas mostrar sua representação? Ou você vai fazer contas com ele? Se for, por que precisa dele formatado?

[quote=jonathanprogrammer]
Resultado volta sem o zero que tu nao quer!

Double valor = 0.00010; String formatado; Double valorFormatado = Double.parseDouble(formatado = new DecimalFormat("#.####").format(valor).replace(',', '.'));[/quote]

Você não testou :frowning:

[quote=bezier curve][quote=jonathanprogrammer]
Resultado volta sem o zero que tu nao quer!

Double valor = 0.00010; String formatado; Double valorFormatado = Double.parseDouble(formatado = new DecimalFormat("#.####").format(valor).replace(',', '.'));[/quote]

Você não testou :frowning: …[/quote]

TESTEI SIM!

Gente, vamos deixar uma coisa clara.

Uma variável double irá representar número de valores iguais, de maneira exatamente igual na memória. Ela guarda valor, e não formato. Por isso, as três versões da função postadas inicialmente estão corretas, sendo a primeira provavelmente a mais eficiente delas.

Quem define o formato é a camada de view. Ou seja, é quem está gerando o relatório. É na hora de converter esse double para a string e exibi-la. Ali você vai dizer que quer mostrar 0s a esquerda, direita, ou que quer que número negativos fiquem entre parênteses, etc… Se ele estiver fazendo uma conversão direta, pouco importa como esse double foi gerado, ele aparecerá com aquele zero no final, já que sempre que não especificar formato, estará a mercê da formatação do Java.

Para resolver o problema, ele terá que usar o comando format no relatório, na hora de exibir o double.

String valorStr = new DecimalFormat("0.####").format(valor); System.out.println(valorStr);

Portanto, esse comando aqui é uma tremenda idiotice:

Double valorFormatado = Double.parseDouble(formatado = new DecimalFormat("#.####").format(valor).replace(',', '.'));

Já que de fato, ele pega um valor, transforma em String, e depois gera um double com exatamente o mesmo valor. Ele pode ser usado apenas como uma forma extremamente ineficiente de truncar tudo que vem após a terceira casa decimal. Mas ele não resolverá o problema do colega, já que o valor final, representado no Double, continuará sendo formatado de maneira incorreta na hora da exibição.

bezier curve, eu não perguntei se 0.001 é igual a 0.0010.


então galera,

eu quero saber pq retorna esse valor: 0.0010 no lugar desse: 0.001.

Eu retorno double pq além exibir o valor eu uso ele para fazer outros calculos!

Vou implementar as soluções q vcs me passaram e jaja volto para falar se deu certo !!!

Já que você perguntou se isso é um bug, de fato foi reportado como bug:

http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=59da64c129d9cb136d9dbeb0a1114?bug_id=4428022

Isso será consertado no Java 7, e em algum build do Java 6 (talvez no update 18, que está para sair); entretanto, isso não provoca nenhum problema em contas. Para a matemática, 0.001 é exatamente a mesma porcaria que 0.0010.

Muito Obrigado!!!

De qualquer forma, não é prudente depender da formatação padrão da classe String. A documentação não garante que ela se manterá igual de uma versão para outra, já que ela não especifica formato. Use um DecimalFormatter na hora de imprimir os dados.