[RESOLVIDO]Erro em ajuste de casas decimais

Bom tenho um servlet que captura valores de um BD, estou tentando limitar o numero de casas decimais com o seguinte código:

[code]try
{…
DecimalFormat df = new DecimalFormat(“0.00”);
while(rs.next()){
ds.setValue(Double.parseDouble(df.format(rs.getDouble(“valor”))), …);

}
…}[/code]
Contudo recebo o seguinte erro:

[code]HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NumberFormatException: For input string: “2770654450,58”
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
java.lang.Double.parseDouble(Double.java:482)
RD_DiarioT.Consulta(RD_DiarioT.java:116)
RD_DiarioT.doPost(RD_DiarioT.java:68)
javax.servlet.http.HttpServlet.service(HttpServlet.java:767)
javax.servlet.http.HttpServlet.service(HttpServlet.java:860)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:249)
java.security.AccessController.doPrivileged(Native Method)
javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:282)
org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:165)

note The full stack trace of the root cause is available in the Sun-Java-System/Application-Server logs.
Sun-Java-System/Application-Server[/code]
Não entendo o que está ocorrendo! Alguém sabe?

A String está usando como separador de casas decimais a vírgula, e você criou o seu number format esperando ponto. Trocando por vírgula deverá resolver seu problema :slight_smile:

Vc precisa fazer tratamento dos números, uma vez q a servlet não trata numeros com virgulas, somente com “.”

Para isso, vc pode utilizar javascript para formatar o número na JSP ou a tag formatNumber assim:

<fmt:formatNumber value="${valor}" pattern=" #,##0.00"/>

e na servlet voce precisa tratar esse número…vc pode usar StringTokenizer e depois o método replace para alterar a virgula pelo "."

Não sei se essa é a melhor opção mas funciona…

Se alguem tiver uma opção mais adequada, por favor me corrijam.

Da uma olhadinha no código de exemplo

//pega os valores ate o ponto final
StringTokenizer token= new StringTokenizer(&lt<valor>&gt, ".");
        
        String valorFinal= "";
        //se tiver algum valor depois do ponto....
       // ele vai continuar percorrendo
        while(token.hasMoreTokens())
        {
          valorFinal+= token.nextToken();
        }
        //agora ele substitui a virgula por ponto final
        valor= valorFinal.replace(',','.');
        // agora só setar o valor no VO
        vo.setValor(Double.parseDouble(valor));

Att

Por causa de “regional settings” é melhor criar seu DecimalFormat assim, se você souber que sempre os dados virão com vírgula em vez de ponto, e os valores negativos irão vir com () em vez do sinal de menos:

            DecimalFormat df =  new DecimalFormat("#,##0.00;(#,##0.00)",
                    new DecimalFormatSymbols(new Locale("pt", "BR")));

Que é um porre, é, mas você tem certeza absoluta que os dados irão ser corretamente interpretados.
Como de costume, encapsule a criação de seu DecimalFormat em uma rotina utilitária.

Meu objeto vem de um BD MySQL e lá estão com ponto e não virgula, mudando a linha para:

DecimalFormat df = new DecimalFormat("0,00");

A resposta foi:

[code]HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NumberFormatException: multiple points
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1084)
java.lang.Double.parseDouble(Double.java:482)
RD_DiarioT.Consulta(RD_DiarioT.java:115)
RD_DiarioT.doPost(RD_DiarioT.java:67)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)

note The full stack trace of the root cause is available in the Apache Tomcat/5.5.9 logs.
Apache Tomcat/5.5.9[/code]

O formato acima é inválido. Quando você faz isso, está dizendo ao Java 3 coisas:

  • Você espera só valores inteiros, sem nada depois do ponto (ou vírgula);
  • Você iria separar o número de 2 em 2 casas (em vez de ser de 3 em 3);
  • O seu número tem de ter exatamente 3 casas.

O correto é usar aquele formato que postei acima. É esquisito mas é que tem de ser daquele jeito.

Thingol utilizei da forma que você falou:

[code] DecimalFormat df = new DecimalFormat("#,##0.00;(#,##0.00)", new DecimalFormatSymbols(new Locale(“pt”, “BR”)));

        ResultSet rs = consulta.executeQuery();
        while(rs.next()){
            ds.setValue(Double.parseDouble(df.format(rs.getDouble("valor"))),[/code]

E deu erro novamente:

[code]HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NumberFormatException: multiple points
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1084)
java.lang.Double.parseDouble(Double.java:482)
RD_DiarioT.Consulta(RD_DiarioT.java:117)
RD_DiarioT.doPost(RD_DiarioT.java:68)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)

note The full stack trace of the root cause is available in the Apache Tomcat/5.5.9 logs.
Apache Tomcat/5.5.9[/code]

Só uma coisinha …

Pegunta: você pegou o valor com getDouble - aqui você tem um valor do tipo double.
Aí você formatou - e transformou em uma string.
Aí você queria converter de novo a string para double - por quê?
E depois, pelo que vi, você queria pegar esse double.

Não era melhor fazer assim:

ds.setValue(rs.getDouble("valor")),

DefaultCategoryDataSet ds = new DefaultCategoryDataSet();

ds.setValue(Double double, String string, String string);

Transformei em double de novo porque o setValue não aceita String no 1º campo. Antes havia feito da forma que você sugeriu:

ds.setValue(rs.getDouble("valor"));

Só que retorna inumeras casas decimais no gráfico! Então resolvi limitar essas casas…

Para limitar as casas, você teria de arredondar o número. Por exemplo:

double limita2casas (double d) {
    return Math.rint (d * 100.0) / 100.0;
}

Só isso. Não tem de converter para string, e ficar indo e voltando e dando mil cambalhotas.

AH desisto nada funciona… Oh “rapazim esperto” que criou o BD utilizou o campo como Double e na hora de delimitar o numero de casas decimais desse campo no BD, ele não delimito. Ai tenho o segintes valores no BD:
120.0000000000000000000000000000000
595.0000000000000000000000000000000

Que significam 120,00 e 595,00 srsr
Pelo que percebi, o Java está pegando e colocando “.”(ponto) de três em três zeros, ou seja não vira decimal e sim aumenta a ordem do numero. Então foi na raça do “emgaloba” mesmo e o código “Perfeito” fica assim:

while(rs.next()){ ds.setValue(LimitaDecimais(rs.getDouble("valor"))

public double LimitaDecimais(double d){ return Math.rint (d * 100.0) / 1000000000.0; }
Mais ou menos o que você me falou Thingol, so que com alguns ZEROS a mais hehe, bom tá perfeito até o momento que der errado os valores! Bom valeu pela paciência ai!! Obrigado!