Cómo redondear un número a N posiciones decimales en Java

1. Información general

En este breve artículo, vamos a buscar la forma de redondear un número de n cifras decimales en Java.

2. Números decimales en Java

Java proporciona dos tipos primitivos que se pueden utilizar para almacenar números decimales: flotante y doble . Double es el tipo utilizado por defecto:

double PI = 3.1415;

Sin embargo, ambos tipos nunca deben usarse para valores precisos , como monedas. Para eso, y también para redondear, podemos usar la clase BigDecimal .

3. Dar formato a un número decimal

Si solo queremos imprimir un número decimal con n dígitos después del punto decimal, simplemente podemos formatear la cadena de salida:

System.out.printf("Value with 3 digits after decimal point %.3f %n", PI); // OUTPUTS: Value with 3 digits after decimal point 3.142

Alternativamente, podemos formatear el valor con la clase DecimalFormat :

DecimalFormat df = new DecimalFormat("###.###"); System.out.println(df.format(PI));

DecimalFormat nos permite establecer explícitamente el comportamiento de redondeo, dando más control de la salida que String.format () usado anteriormente.

4. Redondeo de s dobles con BigDecimal

Para redondear el doble de sa n posiciones decimales, podemos escribir un método auxiliar :

private static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = new BigDecimal(Double.toString(value)); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); }

Hay una cosa importante a tener en cuenta en esta solución: al construir BigDecimal ; debemos utilizar siempre BigDecimal (String) constructor . Esto evita problemas con la representación de valores inexactos.

Podemos lograr lo mismo usando la biblioteca Apache Commons Math:

 org.apache.commons commons-math3 3.5 

La última versión se puede encontrar aquí.

Una vez que se agrega la biblioteca al proyecto, podemos usar el método Precision.round () , que toma dos argumentos: valor y escala:

Precision.round(PI, 3);

De forma predeterminada, utiliza el mismo método de redondeo HALF_UP que nuestro método auxiliar. Por tanto, los resultados deberían ser los mismos.

Tenga en cuenta que podemos cambiar el comportamiento de redondeo pasando el método de redondeo deseado como tercer parámetro.

5. Redondeo de dobles con DoubleRounder

DoubleRounder es una utilidad de la biblioteca decimal4j. Proporciona un método rápido y sin basura para redondear dobles de 0 a 18 decimales.

Podemos obtener la biblioteca (la última versión se puede encontrar aquí) agregando la dependencia al pom.xml :

 org.decimal4j decimal4j 1.0.3 

Ahora, simplemente podemos usar:

DoubleRounder.round(PI, 3);

Sin embargo, DoubleRounder falla en algunos escenarios, por ejemplo:

System.out.println(DoubleRounder.round(256.025d, 2)); // OUTPUTS: 256.02 instead of expected 256.03

6. Método Math.round ()

Otra forma de redondear números es usar el método Math.Round ().

En este caso, podemos controlar n números decimales multiplicando y dividiendo por 10 ^ n :

public static double roundAvoid(double value, int places) { double scale = Math.pow(10, places); return Math.round(value * scale) / scale; }

Este método no se recomienda porque está truncando el valor . En muchos casos, los valores se redondean incorrectamente:

System.out.println(roundAvoid(1000.0d, 17)); // OUTPUTS: 92.23372036854776 !! System.out.println(roundAvoid(260.775d, 2)); // OUTPUTS: 260.77 instead of expected 260.78

Por lo tanto, este método se enumera aquí solo con fines de aprendizaje.

7. Conclusión

En este tutorial rápido, cubrimos diferentes técnicas para redondear números an decimales.

Podemos simplemente formatear la salida sin cambiar el valor, o podemos redondear la variable usando un método auxiliar. También cubrimos algunas bibliotecas que tratan este problema.

El código utilizado durante la discusión se puede encontrar en GitHub.