Buenas.
Estoy estudiando en detalle el estándar C99 del lenguaje C.
En particular el tema de los tipos de punto flotante.
Tengo un problema relativo a las macros de math.h que clasifican valores de punto flotante.
Obtengo resultados "erróneos" (o eso parece) cuando analizo valores subnormales.
Detalles:
El estándar C99 menciona al estándar de números en punto flotante ISO/IEC/IEEE 60559 (también conocido como IEEE 754, para base binaria).
Me interesan las macros que clasifican los valores que puede tomar una constante de punto flotante, con o sin la normativa IEEE 754.
En la librería math.h se encuentra, por ejemplo, la macro
int fpclassify(x)
Da un valor "FP_SUBNORMAL" (valor int definido en math.h) si el parámetro x es un número finito subnormal, en el tipo que fuere.
Según lo que interpreto del estándar C99,
la macro fpclassify() detecta primero el tipo al que pertenece x, digamos float, double o long double.
Luego "se fija" si x es un valor subnormal, en "ese" tipo, y sólo en ese caso devuelve el valor FP_SUBNORMAL.
Ahora bien.
Si yo escribo, por ejemplo:
fpclassify(FLT_MIN / 4.0f)
estoy generando un número subnormal de tipo float,
ya que FLT_MIN es el mínimo punto flotante positivo normal, de tipo float.
Al dividirlo por 4.0f, obtengo de nuevo un valor de punto flotante, que está debajo de ese mínimo, y que todavía es de tipo float.
Si el sistema no soportara valores subnormales, obtendría automáticamente el valor 0.0f como resultado.
Ahora bien, mi compilador, el GCC 4.7.1, con las opciones -std=c99 (y/o -pedantic), no me genera un 0.0f,
sino que da un valor subnormal de tipo float.
Sin embargo, cuando le aplico la macro fpclassify, el resultado que me da es FP_NORMAL, cuando lo esperado era FP_SUBNORMAL, ya que el número es subnormal.
Esta "anomalía" también se produce con double.
En cambio con long double, me da el resultado correcto: FP_SUBNORMAL.
¿Es esto posible? ¿O el compilador GCC tiene un bug en esto?
Otro detalle importante:
La macro FLT_EVAL_METHOD de float.h me da a mí el valor 2.
(Esto quiere decir que el resultado de todos los cálculos se llevan automáticamente a long double).
Mi duda es esta: ¿el estándar C99 condiciona, a través de FLT_EVAL_METHOD, la manera en que se evalúa la macro fpclassify? ¿O es esto una interpretación errónea que hace el compilador GCC? ¿O es un bug?
¿Los valores que me devuelve fpclassify con el compilador GCC 4.7.1 se consideran "los correctos", desde el punto de vista teórico del estándar C99?
Mi impresión es que el comportamiento de fpclassify es equivocado.
Saludos y gracias