Redondear un doble a 2 decimales [duplicado]
Si el valor es 200.3456
, se debe formatear en 200.34
. Si lo es 200
, entonces debería serlo 200.00
.
Aquí hay una utilidad que redondea (en lugar de truncar ) un doble a un número específico de decimales.
Por ejemplo:
round(200.3456, 2); // returns 200.35
Versión original; cuidado con esto
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
Esto falla gravemente en los casos extremos con un número muy alto de decimales (por ejemplo round(1000.0d, 17)
, ) o una parte entera grande (por ejemplo, round(90080070060.1d, 9)
). Gracias a Sloin por señalar esto.
He estado usando lo anterior para redondear felizmente dobles "no demasiado grandes" a 2 o 3 decimales durante años (por ejemplo, para limpiar el tiempo en segundos con fines de registro: 27.987654321987 -> 27.99). Pero supongo que es mejor evitarlo, ya que hay formas más confiables disponibles y también con un código más limpio.
Entonces, usa esto en su lugar
(Adaptado de esta respuesta de Louis Wasserman y ésta de Sean Owen ).
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Tenga en cuenta que HALF_UP
es el modo de redondeo "que se enseña comúnmente en la escuela". Lea detenidamente la documentación de RoundingMode si sospecha que necesita algo más, como Bankers' Rounding .
Por supuesto, si lo prefiere, puede incluir lo anterior en una sola línea:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
Y en todos los casos
Recuerde siempre que las representaciones de coma flotante que utilizan float
y double
son inexactas . Por ejemplo, considere estas expresiones:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
Para mayor exactitud, desea utilizar BigDecimal . Y mientras lo hace, use el constructor que toma un String, nunca el que toma double. Por ejemplo, intenta ejecutar esto:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Algunas excelentes lecturas adicionales sobre el tema:
- Ítem 48: "Evite
float
ydouble
si se requieren respuestas exactas" en Effective Java (2.ª ed.) de Joshua Bloch - Lo que todo programador debe saber sobre la aritmética de punto flotante
Si desea formatear cadenas en lugar de (o además de) números estrictamente redondeados, consulte las otras respuestas.
Específicamente, tenga en cuenta que round(200, 0)
devuelve 200.0
. Si desea generar " 200.00 ", primero debe redondear y luego formatear el resultado para la salida (lo cual se explica perfectamente en la respuesta de Jesper ).
Si solo desea imprimir un double
con dos dígitos después del punto decimal, use algo como esto:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
Si desea tener el resultado en String
lugar de imprimirlo en la consola, utilícelo String.format()
con los mismos argumentos:
String result = String.format("%.2f", value);
O usar clase DecimalFormat
:
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));