java

Java : manejo de dinero con BigDecimal

En este post voy a explicar cómo trabajar con dinero o moneda en Java a través de la clase BigDecimal. Veremos cómo operar (sumar, restar, dividir, multiplicar) y comparar valores con BigDecimal en Java.

El dinero o el tipo de dato monetario son una parte fundamental en muchos sistemas de información; pues las operaciones con el mismo deberían ser precisas, y los redondeos también.

BigDecimal es una manera exacta de representar números, y permite trabajar con mayor precisión que, por ejemplo, el tipo de dato double.

Nota: para usar BigDecimal debes importarlo con:

import java.math.BigDecimal;

El problema con los operadores

Con BigDecimal se trabaja normalmente como con cualquier otro tipo de dato, excepto por los operadores, ya que al no ser datos nativos, no podemos usar:

+ - * /

Ni los lógicos:

< > <= >= ==

Pero existen otros métodos propios de las clases, y eso es justamente lo que explicaré.

Los métodos y constructores

Casi todos los métodos (excepto los constructores) operan con otro BigDecimal, es decir, al sumar, restar, etcétera, debemos pasar otro BigDecimal.

Para construir un BigDecimal podemos pasarle casi todo tipo de datos. Por ejemplo un String o un entero:

BigDecimal bd = new BigDecimal("5");

BigDecimal bd = new BigDecimal(5);

Los métodos que operan con BigDecimal van a devolver otro BigDecimal; no van a modificar internamente al valor. Lo veremos más a fondo en los ejemplos.

Sumar con BigDecimal

Para sumar, hay que llamar al método add. Este método no modificará internamente a la variable, sino que regresará una nueva que ya tiene la suma.

En el siguiente ejemplo se explica mejor:

BigDecimal total = new BigDecimal(0);
BigDecimal bd1 = new BigDecimal(50);
// Lo mismo que total += bd1
total = total.add(bd1);
// Lo mismo que total += 10
total = total.add(new BigDecimal(10));
// Lo mismo que total += 50
total = total.add(new BigDecimal(50));
System.out.println(total.toString()); // 110

Si quieres sumarle a una variable debes definirla como el resultado de llamar a add.

También puedes encadenar los métodos. Por ejemplo:

BigDecimal bd1 = new BigDecimal(50);
BigDecimal bd2 = new BigDecimal(50);
BigDecimal bd3 = bd1.add(bd1).add(bd2);
System.out.println(bd3.toString()); // 150

Restar, multiplicar y dividir

Para restar utiliza substract, si quieres multiplicar utiliza multiply y finalmente para dividir existe el método divide.

Existen otros métodos para operar con BigDecimal que puedes ver aquí.

Realizar comparaciones

No podemos usar los operadores de comparación que conocemos, pero sí los métodos compareTo y equals para realizar comparaciones con BigDecimal.

El método compareTo se llama a partir de un BigDecimal así:

int resultado = unBigDecimal.compareTo(otroBigDecimal);

Y devuelve -1, 0 o 1.

  • -1 en caso de que el primer número sea menor que el segundo
  • 0 en caso de que el primer número sea igual que el segundo
  • 1 en caso de que el primer número sea mayor que el segundo

Esto se explica mejor con el siguiente código de ejemplo:

// Multiplicación = 550, división = 55
if (multiplicacion.compareTo(division) < 0) {
  System.out.println(multiplicacion + " es menor que " + division);
} else if (multiplicacion.compareTo(division) == 0) {
  System.out.println(multiplicacion + " es igual que " + division);

} else if (multiplicacion.compareTo(division) > 0) {
  System.out.println(multiplicacion + " es mayor que " + division);
}

Redondeos con BigDecimal

Podemos controlar la forma de redondear de BigDecimal, a través del método setScale. Este método, al igual que los otros, devuelve al BigDecimal modificado, no lo modifica internamente.

El método setScale recibe dos argumentos: la escala y la forma de redondeo.

La escala es un número entero y en palabras simples son los números que se ven a la derecha del punto.

La forma de redondeo es una constante de RoundingMode (java.Math.RoundingMode) y puede ser CEILING, DOWN, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP, UNNECESARY y UP.

Veamos un ejemplo en donde se ilustran algunos de estos casos:

BigDecimal numero = new BigDecimal("7.3333");
System.out.println("El número original: " + numero.toString());
// Establecer su escala y su forma de redondeo; al llamar
// a setScale se redondea
BigDecimal bdHalfUp = numero.setScale(3, RoundingMode.HALF_UP);
System.out.println("El número con RoundingMode.HALF_UP: " + bdHalfUp.toString());
BigDecimal bdCeiling = numero.setScale(3, RoundingMode.CEILING);
System.out.println("El número con RoundingMode.CEILING: " + bdCeiling.toString());
BigDecimal bdUp = numero.setScale(3, RoundingMode.UP);
System.out.println("El número con RoundingMode.UP: " + bdUp.toString());
BigDecimal bdFloor = numero.setScale(3, RoundingMode.FLOOR);
System.out.println("El número con RoundingMode.FLOOR: " + bdFloor.toString());
El número original: 7.3333
El número con RoundingMode.HALF_UP: 7.333
El número con RoundingMode.CEILING: 7.334
El número con RoundingMode.UP: 7.334
El número con RoundingMode.FLOOR: 7.333

La escala define los decimales a los que se redondea, y la forma define si es hacia arriba o hacia abajo.

Normalmente para redondear suavemente vas a usar las formas de HALF_*, y si tienes dudas puedes leer la documentación oficial.

Poniendo todo junto

Las operaciones, comparaciones y redondeos con BigDecimal se resumen en el siguiente código de ejemplo:

import java.math.BigDecimal;
import java.math.RoundingMode;

class Main {
 public static void main(String[] args) {
  BigDecimal bd1 = new BigDecimal(50);
  BigDecimal bd2 = new BigDecimal(50);
  BigDecimal bd3 = bd1.add(bd1).add(bd2);
  System.out.println(bd3.toString()); // 150
  System.out.println(bd1.equals(bd2)); // true

  BigDecimal total = new BigDecimal(0);
  // Lo mismo que total += bd1
  total = total.add(bd1);
  // Lo mismo que total += 10
  total = total.add(new BigDecimal(10));
  // Lo mismo que total += 50
  total = total.add(new BigDecimal(50));
  System.out.println(total.toString()); // 110

  BigDecimal resta = total.subtract(new BigDecimal(10));
  System.out.println(resta.toString()); // 100

  BigDecimal multiplicacion = total.multiply(new BigDecimal(5));
  System.out.println(multiplicacion.toString()); // 550

  BigDecimal division = multiplicacion.divide(new BigDecimal(10));
  System.out.println(division.toString()); // 55
  // Multiplicación = 550, división = 55
  if (multiplicacion.compareTo(division) < 0) {
   System.out.println(multiplicacion + " es menor que " + division);
  } else if (multiplicacion.compareTo(division) == 0) {
   System.out.println(multiplicacion + " es igual que " + division);

  } else if (multiplicacion.compareTo(division) > 0) {
   System.out.println(multiplicacion + " es mayor que " + division);
  }

  BigDecimal numero = new BigDecimal("7.3333");
  System.out.println("El número original: " + numero.toString());
  // Establecer su escala y su forma de redondeo; al llamar
  // a setScale se redondea
  BigDecimal bdHalfUp = numero.setScale(3, RoundingMode.HALF_UP);
  System.out.println("El número con RoundingMode.HALF_UP: " + bdHalfUp.toString());
  BigDecimal bdCeiling = numero.setScale(3, RoundingMode.CEILING);
  System.out.println("El número con RoundingMode.CEILING: " + bdCeiling.toString());
  BigDecimal bdUp = numero.setScale(3, RoundingMode.UP);
  System.out.println("El número con RoundingMode.UP: " + bdUp.toString());
  BigDecimal bdFloor = numero.setScale(3, RoundingMode.FLOOR);
  System.out.println("El número con RoundingMode.FLOOR: " + bdFloor.toString());

 }
}

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

3 días hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

1 semana hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

1 semana hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

1 semana hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

1 semana hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

1 semana hace

Esta web usa cookies.