Tenías razón con lo del flag
-std=c99 y con
fpclassify(), ejecuta este programilla y verás qué curioso lo que ocurre con la constante:
Código C:
Ver original#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
typedef struct
{
unsigned mnt : 23; // Mantisa
unsigned exp : 8; // Exponente unsigned sgn : 1; // Signo
}
Tflt;
typedef union
{
int intVal;
float fltVal;
Tflt bitVal;
}
Tval;
int main()
{
Tval x;
printf("Sizeof(1.1F) = %d\n", sizeof(1.1F)); x.fltVal = 1.1F;
printf("X (FltHex) = %a\n", x.
fltVal); printf("Cte (FltHex) = %a\n", 1.1F); printf("Cte (CastFltHex) = %a\n", (float)1.1F); printf("Cte (DblHex) = %a\n", 1.1); printf("Cte (LDblHex) = %La\n", 1.1L
); printf("X == 1.1F ?? %s\n", (x.
fltVal == 1.1F)? "SI":"NO"); printf("X == (float)1.1 ?? %s\n", (x.
fltVal == (float)1.1F)? "SI":"NO"); printf("X (flt) = %+f\n", x.
fltVal); printf("X (hex) = 0x%08X\n", x.
intVal); printf("X (sgn) = %u\n", x.
bitVal.
sgn); printf("X (mnt) = %06X\n", x.
bitVal.
mnt); printf("X (fl2) = %a\n", x.
fltVal); printf("Float : FPCLASSIFY: %04X\n", fpclassify
(FLT_MIN
/ (float)4.0)); printf("Double : FPCLASSIFY: %04X\n", fpclassify
(DBL_MIN
/ 4.0)); printf("LDouble : FPCLASSIFY: %04X\n", fpclassify
(LDBL_MIN
/ 4.0L
)); printf("Float : %e FPCLASSIFY: %04X\n", FLT_MIN
, fpclassify
(FLT_MIN
/ (float)4.0)); printf("Double : %e FPCLASSIFY: %04X\n", DBL_MIN
, fpclassify
(DBL_MIN
/ 4.0)); printf("LDouble con %%e : %e FPCLASSIFY: %04X\n", LDBL_MIN
, fpclassify
(LDBL_MIN
/ 4.0L
)); printf("LDouble con %%Le : %Le FPCLASSIFY: %04X\n", LDBL_MIN
, fpclassify
(LDBL_MIN
/ 4.0L
));
return 0;
}
Como puedes ver, si le pido el tamaño de 1.1F me dice que 4 bytes, pero si le pido que me la imprima en hexadecimal lo hace como si tuviera 8 bytes, con lo que la comparación da negativo (pasando del sufijo). En cambio, casteando la constante la comparación da positivo.
Sobre
fpclassify(), en la primera serie de printf me muestra 0x400 para float y double (que corresponde a
FP_NORMAL) y 0x4400 para long double, que corresponde a
FP_SUBNORMAL (que está definido como
FP_NORMAL | FP_ZERO). Hasta aquí todo bien, pero fíjate qué curioso lo que sale en la segunda serie (imprimiendo previamente el valor mínimo para cada tipo), en el tercer printf.
Resumiendo:
Antes de meterse en palabras mayores con cálculos en coma flotante, habrá que hacer algunas minipruebas de este tipo para ver de qué pié cojea el compilador, independientemente del compilador, del estándar al que se adscriba, del sistema operativo y del procesador que se utilice.
Saludos,