En sí se trataba de una igualdad entre números de punto flotante, de tipo double para ser más exacto (o doble si quieres usar una traducción literal, pero esto es programación, así que te quiero pedir que mejor no lo hagas, puede provocar confusiones). Como se trataba de una operación algo mas específica y seguramente compleja como para ponerla de ejemplo, mejor me remitiré al fragmento de código java que éste amigo me proporcionó para ejemplificar lo que pasa:
double test = 0.0;
for (int i = 0; i < 10; i++)
test += 6111403.6;
//6111403.6 sumado 10 veces debería ser 61114036.0
//se agrega cero después del punto, así java lo toma como tipo double
if (test == 61114036.0)
System.out.print("Igual");
else
Syste.out.print("WTF!!??");
Consultando el valor de la variable 'test' al final nos da: test=6.111403600000001E7 en lugar de un varlor de 6.1114036E7 .... ¡así es, algo totalmente inesperado!
¿Pero qué es lo que sucede? bueno, veamos, los números de punto flotante (o coma flotante como le dicen en tierras del mediterráneo) se crearon con la intención de representar números reales. Un número de punto flotante se representa exactamente por la fórmula:
- digitos significantes × baseexponente
Entonces la presición depende de que tantos valores se puedan almacenar de cada una de las partes de la fórumula de arriba, lo cual en ambientes informaticos, como todos saben, es finito, delimitado por el tipo de dato que se utilize para representar ese número real.
Entonces el hecho real es que los números de punto flotante no pueden representar absolutamente todos los números reales, entonces las operaciones que en ellos realizamos nos pueden llevar a situaciones sorpresivas como la que arriba ejemplificamos. Todo esto debido a la presición finita que las computadoras usan para representar estos números.
Para más información al respecto puedes consultar el articulo en la Wikipedia aqui.
Continuando con la historia, lo que mi amigo javero hizo para solucionar su problema, como le bastaba una presición con respecto a los primeros dos dígitos decimales, fue algo como lo siguiente con el valor en cuestión:
test = Math.round(test * 100) / 100;de esta manera ya lo pudo comparar de manera confiable. Cada quien podrá implementar la manera que mejor le convenga, lo que si hay que conservar en mente, esque este tipo de problemas se pueden presentar en cualquier momento si estamos trabajando con valores de punto flotante, por lo tanto debemos tomar medidas si vemos que hay riesgo potencial de que ello signifique errores en nuestros sistemas.
Hay otras alternativas para evitar este problema, una explicación (que además esta en español pero no precisamente para java) se puede ver aqui.
Espero no haber confundido más con respecto a este tema y te sea de alguna utilidad, cualquier comentario aqui estamos... ¡Paz!
No hay comentarios:
Publicar un comentario