Converter String para double erro com NumberFormatException

Pessoal estou com erro ao tentar converter um valor string para double até tentei com float mas deu erro…

Segue o código a baixo …

public static double formatDecimal( int valor) { /recebe o valor em centavos/
int CEM = 100;

	NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
	df.format(valor/CEM); /*converte para reais*/
	
	

	System.out.println(df.format(valor));
	String valor2 = String.valueOf(df.format(valor)).replaceAll(",", ".");  /*esta tirando as virgulas e colocando ponto */
	//double valor2 = Double.valueOf(Limpadados.formataDados( df.format(valor2)));
	//double d = Double.valueOf(valor2).doubleValue();
	double d = Double.parseDouble( valor2 ); /*erro para converter string para double */
	
return d;
} 

Erro ocorre na linha double d = Double.parseDouble( valor2 ); /*erro para converter string para double */

Qual o formato da String valor2 no momento da conversão?

Posta o stacktrace da exceção.

fica com ponto e virugla… por exemplo 1.000,00…

Exception in thread “main” java.lang.NumberFormatException: For input string: “R$1.000.00”
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:543)
at com.m7.sistemam7investimento.Verificador.FormateCasadeCimais.formatDecimal(FormateCasadeCimais.java:35)
at com.m7.sistemam7investimento.Verificador.FormateCasadeCimais.main(FormateCasadeCimais.java:42)

Tente fazer da seguinte forma:

String valor2 = String.valueOf(df.format(valor)).replace(".", "").replace(",", ".");

2 curtidas

Primeiro, String.valueOf serve para converter algum valor para String. Mas o método format já retorna uma String, então usar valueOf neste caso é redundante e desnecessário. Veja:

int valor = 1000;
NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
String comValueOf = String.valueOf(df.format(valor));
String semValueOf = df.format(valor);
System.out.println(comValueOf.equals(semValueOf)); // true (as strings são iguais)

Então não precisa usar String.valueOf.


Segundo, você viu o valor retornado por format?

NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
System.out.println(df.format(1000)); // R$ 1.000,00

Se o valor for 1000, o resultado é R$ 1.000,00. Então o replace que tem ali não é o suficiente, pois você troca a vírgula por ponto, resultando em R$ 1.000.00, e Double.parseDouble não consegue interpretar o “R$” (não faz parte de um valor numérico válido). Então você até poderia remover tudo que não é número:

public static double formatDecimal(int valor) {
    NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
    String valor2 = df.format(valor / 100.0);
    System.out.println(valor2);
    valor2 = valor2.replaceAll("\\D+", ""); // tira tudo que não é número
    // como a string tem os centavos, tenho que dividir por 100 de novo
    return Double.parseDouble(valor2) / 100.0;
}

Ou usar o próprio NumberFormat para fazer o parsing da String:

public static double formatDecimal(int valor) throws ParseException {
    NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
    String valor2 = df.format(valor / 100.0);
    System.out.println(valor2);
    // parse converte a string de volta para número
    return df.parse(valor2).doubleValue();
}

Mas acho que na verdade nada disso é necessário

Você quer que o método retorne o valor dividido por 100, e também imprima o valor formatado? Então faça assim:

public static double formatDecimal(int centavos) {
    double reais = centavos / 100.0;
    NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
    System.out.println(df.format(reais));
    return reais;
}

Não tem porque transformar o valor em String para depois converter esta String de volta para número. Você já tem o valor numérico ali, basta usá-lo.


Na verdade eu também questionaria se o mesmo método deve ser responsável por converter o valor de centavos para reais e ao mesmo tempo mostrar o valor formatado. Eu separaria o cálculo da formatação, pois embora estejam relacionados, são 2 funções diferentes:

public static double converterCentavosParaReais(int centavos) {
    return centavos / 100.0;
}

public static String formatar(double valor) {
    NumberFormat df = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
    return df.format(valor);
}

public static void main(String[] args) throws Exception {
    int centavos = 100000;
    double reais = converterCentavosParaReais(centavos);
    System.out.println(formatar(reais)); // R$ 1.000,00
}
2 curtidas

Boa tarde galera vou testar aqui, mas retorno mais tarde para dizer se funcionou, obrigado por em quanto.

Realmente, um objeto String com valor "R$1.000.00" não é um double válido.

Pessoal estava aqui analisando e se eu fosse fazer as alterações iria alterar muita coisa no sistema, pensei na possibilidade de colocarmos uma mascara nos valores que já estão sendo trazido do banco de dados.

Uma mascara por java script já, hoje os valores são retornados em double então por exemplo o valor de mil reais fica 1000.00 e o objetivo é deixar com uma mascara que fica 1.000,00… Alguém tem uma ideia ? Estou realizando alguns teste aqui com javascript, lembrando que o sistema esta sendo desenvolvido em jsp