Ver Mensaje Individual
  #1  
Antiguo 28-04-2014
Avatar de mlara
[mlara] mlara is offline
Miembro Premium
 
Registrado: jun 2003
Ubicación: Colombia
Posts: 667
Reputación: 21
mlara Va por buen camino
Interpretación de tipo de dato flotante

Hasta hoy varias veces tuve que lidiar con un caso bastante particular relacionado con los tipos de datos de punto flotante en aplicaciones Delphi + Firebird. Casi al final de la historia, por supuesto realizando ciertas consideraciones importantes, opté por trabajar en Firebird con el tipo DOUBLE PRECISION. En la documentación se señala que a diferencia del tipo de dato FLOAT, este tiene un tamaño de 64 bits y no de 32 bits, con una precisión de 15 dígitos, y no de 7 dígitos. De esta forma nunca tuve inconveniente alguno en particularmente almacenar o recuperar valores reales.

DOUBLE PRECISION: 64 bits(a), 2.225 x 10^-308 to 1.797 x 10^308, IEEE double precision (15 digits)
FLOAT: 32 bits, 1.175 x 10^-38 to 3.402 x 10^38, IEEE single precision (7 digits)
NUMERIC(p, s): 16, 32, o 64 bits (variable)
DECIMAL(p, s): 16, 32, o 64 bits (variable)

(a) El tamaño de DOUBLE es dependiente de la plataforma*. La mayoría de las plataformas soportan el tamaño de 64 bits.

* No se refiere a si la plataforma es de 32 o de 64 bits. La respuesta a la pregunta ¿Qué plataformas no soportan el tamaño de 64 bits para el tipo de dato DOUBLE de Firebird? en realidad hasta este momento no la conozco.

Y a qué viene todo esto? Bueno, hace poco llegó un cliente con un equipo en el que un sistema desarrollado por mí no funcionaba correctamente al realizar operaciones comunes. Al realizar las pruebas respectivas encontré muy extraño el caso, más aún porque se trataba de un error no esperado en un consulta extremadamente simple. Para poder reproducir el error estando muy seguro de que la causa no era mi implementación de la base de datos, quise hacerlo todo desde cero:

Código SQL [-]
CREATE TABLE Testing (F1 DOUBLE PRECISION)

Código SQL [-]
INSERT INTO Testing VALUES(1.25);
INSERT INTO Testing VALUES(0.05);
INSERT INTO Testing VALUES(3.8);
INSERT INTO Testing VALUES(8.999);

Luego, al realizar la consulta de cada registro de forma independiente, así:

Código SQL [-]
SELECT * FROM Testing WHERE F1 = VALOR

, sucede que sólo funcionaba para el primer registro, es decir para VALOR = 1.25. Cuando VALOR era igual a 0.05 o 3.8 u 8.999 no se obtenía resultado alguno, o dicho de otra forma, se obtenía un conjunto vacío. La única forma de hacer que funcionara para los demás registros fue realizando la consulta de esta forma:

Código SQL [-]
SELECT * FROM Testing WHERE F1 = CAST(VALOR AS DOUBLE PRECISION)

Al final, y para saber si tenía algún problema con un equipo en particular, no fuera que me llegase después algún caso parecido, realicé esta consulta:

Código SQL [-]
SELECT IIF(8.99 = CAST(8.99 AS DOUBLE PRECISION), 1, 2) FROM RDB$DATABASE

El resultado esperado es 1, pero si se trata del mismo caso del cliente en cuestión, se obtendrá un 2.

Por supuesto que realicé el mismo ejercicio en varios equipos. En todos no hubo problema alguno, excepto en el equipo del cliente. ¿Qué tiene de especial? No lo sé en verdad. Se trata de un portátil HP G42 con procesador Intel Core i3 M350 a 2.27 GHz con 3 GB en RAM, sistema operativo Windows 7 Home Basic de 32 bits ejecutando una aplicación con Firebird embebido versión 2.1.4.18393.

Lo único que se me ocurre es que el equipo del cliente sea una de esas plataformas que no soporta el tipo de dato DOUBLE PRECISION de 64 bits, de tal forma que al realizar Firebird la conversión internamente no se obtenga el resultado esperado. Hay que recordar que este post lo inicio afirmando que antes tuve inconvenientes con los tipos de datos de punto flotante de 32 bits.

Decidí compartir este caso ya que estuve consultando y no encontré información alguna al respecto, y de haber alguien que sepa exactamente qué sucede seguramente además de mí alguien agradecerá su aporte.
__________________
...y mañana caminaré por las calles pasando inadvertido, como siempre.

Última edición por mlara fecha: 28-04-2014 a las 23:01:01.
Responder Con Cita