Pues parece ser, que por temas de cómo se almacenan los nº
reales en los ordenadores, se producen problemas de precisión cuando se
realizan operaciones con ellos debido a que el ordenador trabaja con nº
binarios. Yo no sé a vosotros, pero que yo recuerde, a mi esto no me lo
contaron en la carrera, y como hasta ahora no tuve que trabajar con nº reales
haciendo operaciones, pues no me he percatado del PROBLEMON :-O
Por ejemplo, vamos a ver que pasa con Java y Visual Basic
(ojo, que en javascript también existe este problema). El índice será:
1- Problema con
JAVA
2- Problema con
Visual Basic
3- Solución
para JAVA
4- Solución
para Visual Basic
NOTA: Visual Basic no lo domino (Bueno, y java tampoco ;-) )
, si cometo algún error que alguien me lo diga.
Por cierto, me faltaría investigar como se soluciona el
problema en JavaScript, si alguien
tiene la solución ya sabe ;-))
1 –
Problema con JAVA:
1 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1 que tendría que devolver 0.5
en java se obtendría:
- si utilizamos un float: 0.4999999
- si utilizamos un double: 0.5000000000000001
Para que se muestre por pantalla el valor correcto, en java
habría que formatear el nº para que solo muestre x dígitos decimales de
precisión con DecimalFormat formateador = new
DecimalFormat("####.####");
Pero esto no soluciona el problema, ya que aunque se
visualiza bien lo que se almacena es incorrecto, y cuando operemos con estos
valores acabaremos con errores.
Os dejo aquí un ejemplo:
2 – Problema con Visual Basic
Los equivalentes son single
y double.
Con double: el valor que
almacena es el mismo que en java: 0.5000000000000001 pero si lo
mostramos por pantalla no nos enteramos, porque Visual Basic parece ser que ya
se encarga de formatearlo automáticamente, ¡pero ojo!, si por ejemplo hacemos una
comparación (o hacemos operaciones con ellos) tenemos el problema.
Como se puede observar en el debug, lo que pensábamos que son iguales
(f1 y f2) no lo son ;-)) y por supuesto el resultado que sale por pantalla es:
3 - Solución para JAVA
La solución es utilizar la clase BigDecimal (realiza los cálculos en decimal en vez de en
binario). En este enlace se explica
muy bien y de forma muy breve: http://www.javamexico.org/ blogs/luxspes/por_que_usar_ bigdecimal_y_no_double_para_ calculos_aritmeticos
Para el ejemplo que he puesto, el código quedaría de la
siguiente forma:
import java.math.BigDecimal;
……
BigDecimal
uno = new BigDecimal("1");
BigDecimal
ceroUno = new BigDecimal("0.1");
BigDecimal
f3 =
uno.subtract(ceroUno). subtract(ceroUno).subtract( ceroUno).subtract(ceroUno). subtract(ceroUno);
System.out.println("BigDecimal f3: (1 - 0,1 - 0,1 - 0,1 - 0,1 - 0,1) =
" + f3);
4 – Solución para Visual Basic
Visual Basic tiene un tipo primitivo especifico para esto, decimal por tanto bastaría con declarar las
variables de este tipo:
Dim
f1 as Decimal
Dim
f2 as Decimal
