Tengo problemas para entender las reglas de C con respecto a la precisión que se debe asumir al imprimir dobles o al convertir cadenas a dobles. El siguiente programa debe ilustrar mi punto:Comportamiento extraño al convertir cadenas de C a dobles desde
#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
double x, y;
const char *s = "1e-310";
/* Should print zero */
x = DBL_MIN/100.;
printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);
/* Trying to read in floating point number smaller than DBL_MIN gives an error */
y = strtod(s, NULL);
if(errno != 0)
printf(" Error converting '%s': %s\n", s, strerror(errno));
printf("y = %e\n", y);
return 0;
}
La salida que consigo cuando compilar y ejecutar este programa (en un Core 2 Duo con gcc 4.5.2) es:
DBL_MIN = 2.225074e-308, x = 2.225074e-310
Error converting '1e-310': Numerical result out of range
y = 1.000000e-310
Mis preguntas son :
- ¿Por qué x se imprime como un número distinto de cero? Sé que los compiladores a veces promueven los dobles a tipos de precisión más altos para fines de computación, pero no deberían imprimir tratar x como un doble de 64 bits.
- Si la biblioteca C secretamente usa números de punto flotante de precisión extendida, ¿por qué strtod establece errno cuando intenta convertir estos números pequeños? ¿Y por qué produce el resultado correcto de todos modos?
- ¿Es este comportamiento solo un error, resultado de mi hardware particular y mi entorno de desarrollo? (Lamentablemente no puedo probar en otras plataformas en este momento).
Gracias por cualquier ayuda que pueda dar. Trataré de aclarar el problema a medida que recibo retroalimentación.
Por un lado:' DBL_MIN = 2.225074e-308' no tiene mucho sentido ya que el valor mínimo de IEEE DP es '4.94066e-324'. Esto explica por qué dividir por' 100' todavía funciona correctamente. Pero la pregunta es por qué 'DBL_MIN' no es' 4.94066e-324'. – Mysticial
Aclarado a continuación: DBL_MIN es el valor _normalised_ más pequeño –