truncar round redondear imprimir formato float decimales con java double rounding numberformatexception

round - redondear a dos decimales java



Doble valor para redondear en Java (9)

El problema es que utiliza un formateador de localización que genera un punto decimal específico del entorno local, que es "," en su caso. Pero Double.parseDouble () espera doble literal no localizado. Puede resolver su problema utilizando un método de análisis específico de la configuración regional o cambiando la configuración regional de su formateador a algo que use "." como el punto decimal. O mejor aún, evite el formateo innecesario usando algo como esto:

double rounded = (double) Math.round(value * 100.0) / 100.0;

Tengo un doble valor = 1.068879335 Quiero redondearlo con solo dos valores decimales como 1.07.

Intenté así

DecimalFormat df=new DecimalFormat("0.00"); String formate = df.format(value); double finalValue = Double.parseDouble(formate) ;

esto me está dando esta siguiente excepción

java.lang.NumberFormatException: For input string: "1,07" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224) at java.lang.Double.parseDouble(Double.java:510)

¿Puede alguien decirme qué está mal con mi código?

finalmente necesito el valor final = 1.07;


Esto no es posible de la manera solicitada porque hay números con dos decimales que no se pueden expresar con los números de coma flotante IEEE (por ejemplo, 1/10 = 0.1 no puede expresarse como Double o Float ). El formateo siempre debe ocurrir como el último paso antes de presentar el resultado al usuario.

Supongo que estás preguntando porque quieres lidiar con los valores monetarios. No hay forma de hacer esto confiablemente con números de coma flotante, debería considerar cambiar a aritmética de punto fijo. Esto probablemente significa hacer todos los cálculos en "centavos" en lugar de "dólares".


Hay algo fundamentalmente mal con lo que estás tratando de hacer. Los valores binarios de puntos flotantes no tienen decimales. No se puede redondear significativamente uno a un número dado de decimales, porque la mayoría de los valores decimales "redondos" simplemente no se pueden representar como una fracción binaria. Es por eso que nunca se debe usar float o double para representar el dinero.

Por lo tanto, si desea lugares decimales en su resultado, ese resultado debe ser una String (que ya obtuvo con el DecimalFormat ), o un BigDecimal (que tiene un método setScale() que hace exactamente lo que desea). De lo contrario, el resultado no puede ser lo que quieres que sea.

Lea The Floating-Point Guide para más información.


La solución de Live @ Sergey pero con división entera.

double value = 23.8764367843; double rounded = (double) Math.round(value * 100) / 100; System.out.println(value +" rounded is "+ rounded);

huellas dactilares

23.8764367843 rounded is 23.88

EDITAR: Como señala Sergey, no debería haber diferencia entre multiplicar double * int y double * double y dividir double / int y double / double. No puedo encontrar un ejemplo donde el resultado sea diferente. Sin embargo, en x86 / x64 y otros sistemas existe una instrucción de código de máquina específica para valores mixtos dobles, que creo que utiliza la JVM.

for (int j = 0; j < 11; j++) { long start = System.nanoTime(); for (double i = 1; i < 1e6; i *= 1.0000001) { double rounded = (double) Math.round(i * 100) / 100; } long time = System.nanoTime() - start; System.out.printf("double,int operations %,d%n", time); } for (int j = 0; j < 11; j++) { long start = System.nanoTime(); for (double i = 1; i < 1e6; i *= 1.0000001) { double rounded = (double) Math.round(i * 100.0) / 100.0; } long time = System.nanoTime() - start; System.out.printf("double,double operations %,d%n", time); }

Huellas dactilares

double,int operations 613,552,212 double,int operations 661,823,569 double,int operations 659,398,960 double,int operations 659,343,506 double,int operations 653,851,816 double,int operations 645,317,212 double,int operations 647,765,219 double,int operations 655,101,137 double,int operations 657,407,715 double,int operations 654,858,858 double,int operations 648,702,279 double,double operations 1,178,561,102 double,double operations 1,187,694,386 double,double operations 1,184,338,024 double,double operations 1,178,556,353 double,double operations 1,176,622,937 double,double operations 1,169,324,313 double,double operations 1,173,162,162 double,double operations 1,169,027,348 double,double operations 1,175,080,353 double,double operations 1,182,830,988 double,double operations 1,185,028,544


Podría intentar definir un nuevo DecimalFormat y usarlo como un doble resultado para una nueva variable doble.

Ejemplo dado para hacerte entender lo que acabo de decir.

double decimalnumber = 100.2397; DecimalFormat dnf = new DecimalFormat( "#,###,###,##0.00" ); double roundednumber = new Double(dnf.format(decimalnumber)).doubleValue();


Pruebe esto: org.apache.commons.math3.util.Precision.round (doble x, escala int)

Ver: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

La página principal de la Biblioteca de Matemáticas de Apache Commons es: http://commons.apache.org/proper/commons-math/index.html

La implementación interna de este método es:

public static double round(double x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } public static double round(double x, int scale, int roundingMethod) { try { return (new BigDecimal (Double.toString(x)) .setScale(scale, roundingMethod)) .doubleValue(); } catch (NumberFormatException ex) { if (Double.isInfinite(x)) { return x; } else { return Double.NaN; } } }


Puedes usar el formato como here ,

public static double getDoubleValue(String value,int digit){ if(value==null){ value="0"; } double i=0; try { DecimalFormat digitformat = new DecimalFormat("#.##"); digitformat.setMaximumFractionDigits(digit); return Double.valueOf(digitformat.format(Double.parseDouble(value))); } catch (NumberFormatException numberFormatExp) { return i; } }


Tenga en cuenta la coma en su cadena: "1,07". DecimalFormat utiliza una cadena separadora específica del entorno local, mientras que Double.parseDouble() no lo hace. Como usted vive en un país donde el separador decimal es ",", no puede analizar su número.

Sin embargo, puede usar el mismo DecimalFormat para analizarlo de nuevo:

DecimalFormat df=new DecimalFormat("0.00"); String formate = df.format(value); double finalValue = (Double)df.parse(formate) ;

Pero realmente deberías hacer esto en su lugar:

double finalValue = Math.round( value * 100.0 ) / 100.0;

Nota: Como se ha señalado, solo debe usar el punto flotante si no necesita un control preciso sobre la precisión. (Los cálculos financieros son el principal ejemplo de cuándo no usarlos).


double TotalPrice=90.98989898898; DecimalFormat format_2Places = new DecimalFormat("0.00"); TotalPrice = Double.valueOf(format_2Places.format(TotalPrice));