Como trabajar con cálculos financieros en JAVA

Para trabajar con valores monetarios en un programa financiero. Cuando tratas con valor “dinero”, está siempre vienen a una pregunta, debo usar variables float o double para representar los valores monetarios?

1. Los valores monetarios en Java – dobles

Aquí hay un ejemplo de usar double para representar los valores monetarios en Java.

System.out.println("--- Impresión Normal con Double -----");
System.out.println(2.00 - 1.1);//0.8999999999999999
System.out.println(2.00 - 1.2);//0.8
System.out.println(2.00 - 1.3);//0.7
System.out.println(2.00 - 1.4);//0.6000000000000001
System.out.println(2.00 - 1.5);//0.5
System.out.println(2.00 - 1.6);//0.3999999999999999
System.out.println(2.00 - 1.7);//0.30000000000000004
System.out.println(2.00 - 1.8);//0.19999999999999996
System.out.println(2.00 - 1.9);//0.10000000000000009
System.out.println(2.00 - 2);//0.0
System.out.println(3.6 - 2.4);//1.19999999999 or 1.20000000003
double unCentavo = 0.01;
double suma=unCentavo+unCentavo+unCentavo+unCentavo+unCentavo+unCentavo;
System.out.println(suma);// si piensas que es 0.06 estas equivocado, se imprime 0.060000000000000005
 2. Los valores monetarios en Java – BigDecimal

Para evitar el problema decimal anterior, se puede usar BigDecimal para representar los valores monetarios.

System.out.println("--- Usando BigDecimal-----");
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.1")));//0.90
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.2")));//0.80
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.3")));//0.70
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.4")));//0.60
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.5")));//0.50
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.6")));//0.40
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.7")));//0.30
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.8")));//0.20
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.9")));//0.10
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("2")));//0.00
java.math.BigDecimal unCentavo = new java.math.BigDecimal("0.01");
java.math.BigDecimal suma=unCentavo.add(unCentavo).add(unCentavo).add(unCentavo).add(unCentavo).add(unCentavo);// se imprime 0.06
System.out.println(suma);
Conclusión

Las computadoras no cuentan como nosotros, las computadoras “cuentan en binario”, nosotros, contamos en decimal. Cuando usamos una variable float o double, estamos dejandole al microprocesador de la computadora el trabajo de efectuar los cálculos directamente (con su coprocesador matemático) pero como las computadoras “piensan” en binario, cometen errores de precisión diferentes a los nuestros. Por ejemplo, nosotros los humanos, tenemos un problema para representar a la tercera parte de “1” (1/3), y la escribimos: 0.3333333333333333333… (hasta el infinito), en nuestro sistema decimal (base 10), no hay modo de representar a un tercio de un entero. Si por otro lado, nuestro sistema fuera base “9”, entonces representariamos la tercera parte de un entero simplemente con : “0.3” (y seria mas preciso que cualquier lista larga de números “3” en base 10.

En binario (base 2), no se puede representar a 1/10 (la décima parte de 1) ni a 1/100 (la centésima parte de 1) y por eso, cuando nosotros escribimos “0.01” la computadora lo entiende como 1100110011001100110011001100110011… (hasta el infinito) y efectuá el calculo incorrectamente (desde nuestro punto de vista “decimal”).

Si hacen sistemas financieros, los pequeños errores de calculo acumulados con varios centavos pueden resultar en reportes cuyos cálculos diferirán de las operaciones que normalmente realizamos los humanos. Para resolver este problema, en Java se incluye la clase BigDecimal, que si bien realiza los cálculos mas lento que “Double/double” los realiza del mismo modo que los humanos (en base 10) y así evitamos el problema.

Algunos microprocesadores especializados si son capaces de efectuar “por hardware” los cálculos de forma decimal. Desafortunadamente, hasta donde se, ninguno de los microprocesadores comúnmente encontrados en equipos de escritorio cuentan con esta capacidad.

En Java, se recomienda usar BigDecimal para representar los cálculos monetarios . Sin embargo cálculos BigDecimal son más lentos que los que tienen cálculos de tipos de datos primitivos, que pueden ser un problema para los programas con cálculos decimales, pero hay no debería ser problema para la mayoría de los programas.

Otros Artículos para trabajar con cálculos matemáticos:

Un comentario

  1. Carlos dice:

    Muy buen comentario, esa siempre ha sido una de mis grandes dudas

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *