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));