Como usar las clases MathContext y BigDecimal en Java [SOLUCIONADO]

Temas sobre programación ( php, c, sql, html, perl, python, ruby, java, bash, etc ) y recursos ( herramientas, frameworks, hosting, cms, etc )

Moderadores: akodo, maiku

Responder
Avatar de Usuario
Juanp_1982
Forista Mayor
Forista Mayor
Mensajes: 913
Registrado: Dom Ago 13, 2006 7:00 am
Ubicación: Toronto, Canada

Como usar las clases MathContext y BigDecimal en Java [SOLUCIONADO]

Mensaje por Juanp_1982 » Vie Feb 10, 2012 1:48 am

Hola a Todos!

tengo que utilizar estas clases para un proyecto que estoy haciendo, el Tio Google me recomendo una pagina muy buena en Oracle pero estoy estancado en este punto.

el asunto es que el metodo recibe un double con "x" decimales, y yo quiero redondearlos y dejarlo con solo 2 decimanles de tal manera que si recibo: 1452,78965412 despues de formatearlo quedaria 1452,79 pero la forma como estoy implementando este metodo me da otro resultado que no quiero...

Código: Seleccionar todo

public double formatMoney(double money) {
        double money_formatted = 0.00;

        if (money >= 0) {
            MathContext format = new MathContext(2, RoundingMode.HALF_UP);
            BigDecimal formatted_1 = new BigDecimal(money, format);

            System.out.println(formatted_1); //<================= aqui me da 1.5E+3
            money_formatted = formatted_1.doubleValue(); 
            System.out.println(money_formatted); //<==============aqui me da 1500.0
        }

        return money_formatted;
    }
probe con el metodo round() y creando otro objeto BigDecimal pero me da exactamente los mismo resultados
la pregunta es, que estoy haciendo mal? como lo puedo arreglar?
Última edición por Juanp_1982 el Sab Feb 11, 2012 7:55 pm, editado 3 veces en total.
La Hora Mas oscura es una antes de que Amanesca (Anonimo)
Avatar de Usuario
akodo
Moderador
Moderador
Mensajes: 1457
Registrado: Mié Nov 28, 2007 8:00 am
Ubicación: En la X del explorer (pulse para llamar)

Re: Como usar las clases MathContext y BigDecimal en Java

Mensaje por akodo » Sab Feb 11, 2012 12:41 am

Creo que estás malinterpretando el significado de "precision" en el MathContext. Según he visto por ejemplos, viene a ser el número de dígitos que se guardan, sean o no decimales. Para tu caso, si pasas como parámetro 1452,78965412 y precision 2 lo que te va a guardar son los dos primeros dígitos redondeando como has indicado, esto es 1500,0000; si indicaras como precision 3 tendrías 1450,0000.

En este enlace te lo explican con ejemplos

Visto algo de documentación e información sobre el tema, te sugiero que pruebes algo así:

Código: Seleccionar todo

String dvalue = Double.toString(doubleParam);
BigDecimal bd = new BigDecimal(dvalue,MathContext.UNLIMITED);  //creo que es un poco duro, pero debería funcionar

System.out.println(bd.setScale(2,RoundingMode.HALF_UP));

double retVale = bd.setScale(2,RoundingMode.HALF_UP);
System.out.println(retValue);
Convendría que leyeras un poco más a fondo el javadoc en cuestión porque el constructor BigDecimal(double) está un poco desaconsejado, y se recomienda utilizar el BigDecimal(String). No es que tu problema este directamente relacionado con eso, pero es bueno tenerlo en cuenta.

De todas formas, utilizar esas clases para formateo queda feo, y más usándolas internamente. Yo preferiría que la función tuviera como parámetros un BigDecimal o String, y devolviera un BigDecimal, pero eso ya es cosa tuya.
Descargue el gestor de mp3 "Music Manager" -> ([url=http://ctrlalt.iespana.es]mmlf[/url])
Última versión del gestor "Music Manager" -> ([url=http://sourceforge.net/projects/jmusicmanager/]jmmm[/url])
Avatar de Usuario
Juanp_1982
Forista Mayor
Forista Mayor
Mensajes: 913
Registrado: Dom Ago 13, 2006 7:00 am
Ubicación: Toronto, Canada

Re: Como usar las clases MathContext y BigDecimal en Java

Mensaje por Juanp_1982 » Sab Feb 11, 2012 7:54 pm

akodo escribió:Creo que estás malinterpretando el significado de "precision" en el MathContext. Según he visto por ejemplos, viene a ser el número de dígitos que se guardan, sean o no decimales. Para tu caso, si pasas como parámetro 1452,78965412 y precision 2 lo que te va a guardar son los dos primeros dígitos redondeando como has indicado, esto es 1500,0000; si indicaras como precision 3 tendrías 1450,0000.

En este enlace te lo explican con ejemplos

Visto algo de documentación e información sobre el tema, te sugiero que pruebes algo así:

Código: Seleccionar todo

String dvalue = Double.toString(doubleParam);
BigDecimal bd = new BigDecimal(dvalue,MathContext.UNLIMITED);  //creo que es un poco duro, pero debería funcionar

System.out.println(bd.setScale(2,RoundingMode.HALF_UP));

double retVale = bd.setScale(2,RoundingMode.HALF_UP);
System.out.println(retValue);
Convendría que leyeras un poco más a fondo el javadoc en cuestión porque el constructor BigDecimal(double) está un poco desaconsejado, y se recomienda utilizar el BigDecimal(String). No es que tu problema este directamente relacionado con eso, pero es bueno tenerlo en cuenta.

De todas formas, utilizar esas clases para formateo queda feo, y más usándolas internamente. Yo preferiría que la función tuviera como parámetros un BigDecimal o String, y devolviera un BigDecimal, pero eso ya es cosa tuya.
akodo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! me has salvado la vida!!! muchas gracias!!!!! hices unas pequenias modificaciones, pero basicamente sigue siendo tu codigo!!! muchas gracias
Editado: me adelante un poco, funciona para el ejemplo que estamos tratando, pero si introduzco por ejemplo 12.00 me devuelve 12.0 y me gustaria dos decimales, pero por lo menos ya estoy mas cerca :-)

Código: Seleccionar todo

 public double formatMoney(double money) {
        double money_formatted = 0.00;

        if (money >= 0) {
            String dvalue = Double.toString(money);
            BigDecimal bd = new BigDecimal(dvalue, MathContext.UNLIMITED);  //creo que es un poco duro, pero debería funcionar
            BigDecimal bd2;
            bd2 = bd.setScale(2, RoundingMode.HALF_UP);
            money_formatted = bd2.doubleValue();
            System.out.println(money_formatted);

        }

        return money_formatted;
    }
Editado: resulta que Java no le gusta 0.00 y lo guarda como 0.0 haga lo que haga para mantenerlo como quiero, ashi que no hay nada que hacer
La Hora Mas oscura es una antes de que Amanesca (Anonimo)
Avatar de Usuario
akodo
Moderador
Moderador
Mensajes: 1457
Registrado: Mié Nov 28, 2007 8:00 am
Ubicación: En la X del explorer (pulse para llamar)

Re: Como usar las clases MathContext y BigDecimal en Java [SOLUCIONADO]

Mensaje por akodo » Sab Feb 11, 2012 11:54 pm

Deberías considerar olvidarte de utilizar double y utilizar BigDecimal, o al menos crear una clase "Money" que utilice BigDecimal internamente sin exponerlo a otras clases. Incluso aún teniendo la posibilidad de convertirlo a double no debería ser tu responsabilidad el formatearlo fuera de la clase "Money".

Dicho esto, podrías pobrar a ver que sale con el método "toPlainString" de la clase BigDecimal (después de hacer el setScale)
Descargue el gestor de mp3 "Music Manager" -> ([url=http://ctrlalt.iespana.es]mmlf[/url])
Última versión del gestor "Music Manager" -> ([url=http://sourceforge.net/projects/jmusicmanager/]jmmm[/url])
Avatar de Usuario
Juanp_1982
Forista Mayor
Forista Mayor
Mensajes: 913
Registrado: Dom Ago 13, 2006 7:00 am
Ubicación: Toronto, Canada

Re: Como usar las clases MathContext y BigDecimal en Java [SOLUCIONADO]

Mensaje por Juanp_1982 » Dom Feb 12, 2012 1:41 am

eso seria agradable, pero esto es un programa para la univ y estoy siguiendo las especificaciones que pidio el profesor... :-(
La Hora Mas oscura es una antes de que Amanesca (Anonimo)
Responder
  • Similar Topics
    Respuestas
    Vistas
    Último mensaje