Limitar el número de decimales de un double o un float en Java

Cuando trabajamos en Java con números decimales (double, float y BigDecimal) y hacemos operaciones con ellos el resultado puede que tenga una cantidad de decimales mayor de la esperada y que queramos limirtarlos ya sea simplemente para representarlos o para guardarlos y trabajar con ellos, dependiendo del objetivo podemos usar unas u otras formas para controlar la cantidad de decimales y formatearlos adecuadamente.

Limitar el número de decimales con DecimalFormat

Usando DecimalFormat podemos obtener los números con decimales con el formato que deseemos, en el siguiente ejemplo tenemos 2 patrones distintos para formatear un double por ejemplo con solo 2 decimales, en el primero fijamos que siempre tenga los dos decimales aunque el número tenga menos decimales en cuyo caso rellenará con 0s y en el otro también va a tener como maximo 2 decimales pero si el número a formatear tiene menos no le hace nada.


float numero1 = 3.3f;
double numero2 = 3.33333d;

DecimalFormat formato1 = new DecimalFormat("#.00");
System.out.println(formato1.format(numero1)); // Resultado => 3,30
System.out.println(formato1.format(numero2)); // Resultado => 3,33
        
DecimalFormat formato2 = new DecimalFormat("#.##");
System.out.println(formato2.format(numero1)); // Resultado => 3,3
System.out.println(formato2.format(numero2)); // Resultado => 3,33

DecimalFormat es una buena solución si lo que queremos hacer es simplemente formatear el número para representarlo, además podemos cambiar el separador de decimales por el que nosotros elijamos, vamos a ver el mismo ejemplo pero usando como separador el «.» en lugar de la «,».


float numero1 = 3.3f;
double numero2 = 3.33333d;

DecimalFormatSymbols separadoresPersonalizados = new DecimalFormatSymbols();
separadoresPersonalizados.setDecimalSeparator('.');

DecimalFormat formato1 = new DecimalFormat("#.00", separadoresPersonalizados);
System.out.println(formato1.format(numero1)); // Resultado => 3.30
System.out.println(formato1.format(numero2)); // Resultado => 3.33
        
DecimalFormat formato2 = new DecimalFormat("#.##", separadoresPersonalizados);
System.out.println(formato2.format(numero1)); // Resultado => 3.3
System.out.println(formato2.format(numero2)); // Resultado => 3.33

Limitar el número de decimales con operaciones matematicas en Java

Tener un método para representar los números decimales a nuestro gusto esta bien pero en ocasiones esos números los vamos a querer almacenar con menos decimales y para ese caso el DecimalFormat no nos sirve, la solución es redondear el número, pero como la operación de redondear nos quitara todos los decimales antes tenemos que mover la coma hacia a la izquierda multiplicando el número por 10^numero_decimales_finales, y despues de redondear ese número lo dividimos por ese mismo número para recupera los decimales.


double precio = 3.3d;
double descuento = 0.15d;
double precioFinal = precio - (precio * descuento);
System.out.println(precioFinal); // Resultado => 2.8049999999999997 si no imprime 2.805
        
precioFinal = Math.round(precioFinal * 100) / 100d;
System.out.println(precioFinal); // Resultado => 2.81

// Operaciones sobre el numero para dejar solo 2 decimales paso a paso
// Numero original - 2.8049999999999997
// 1. Multiplicamos por 100 (10^2) - 280.5
// 2. Redondeamos - 281
// 3. Dividimos por 100 (10^2) - 2.81

Con esta sencilla operación podemos dejar nuestros doubles o floats con los decimales que queramos como en ese ejemplo. Para mantener el código más limpio podemos crearnos una función como esta y ademas así lo tenemos mejor preparado por si en algun momento queremos cambiar el número de decimales o si queremos que sea configurable.


public static Double formatearDecimales(Double numero, Integer numeroDecimales) {
    return Math.round(numero * Math.pow(10, numeroDecimales)) / Math.pow(10, numeroDecimales);
}

Aunque he usado el método Math.round podriamos usar también Math.ceil o Math.floor dependiendo del modo en el que queramos hacer el redondeo.

Limitar el número de decimales con BigDecimal

Y la última opción que vamos a ver es utilizar la clase BigDecimal de Java, ya sea para sustituir directamente al double o solo para hacer el formateo.

Creamos el BigDecimal con nuestro double del precio con descuento que tiene más decimales de los que queremos y le indicamos el número de decimales y el modo de redondeo que tiene que aplicar y listo ya tenemos el número con solo 2 decimales, además podemos volver a pasarlo a double si queremos.


double precio = 3.3d;
double descuento = 0.15d;
double precioFinal = precio - (precio * descuento);

BigDecimal bigDecimal = new BigDecimal(precioFinal).setScale(2, RoundingMode.UP);
System.out.println(bigDecimal.doubleValue()); // Resultado => 2.81