Ver Mensaje Individual
  #5 (permalink)  
Antiguo 18/02/2013, 08:53
argentinator
 
Fecha de Ingreso: junio-2005
Ubicación: Argentina
Mensajes: 90
Antigüedad: 18 años, 11 meses
Puntos: 2
Respuesta: Números Subnormales en C (estándar C99 y GCC 4.7)

Creo que no me he explicado.

El cast a long double se lo hice tanto a la constante 1.1F como a la variable x, la cual he definido, como se ve, de tipo "float", y a la que encima le cargué el mismo valor constante 1.1F.

En ambos casos, el printf() tiene que mostrar el mismo valor hexadecimal (eso creo yo), ya que todos los procesos que describís, de cargar en la FPU, luego en RAM, etc., tienen que ser los mismos en ambos casos.

Pero los valores que me muestra el printf() en hexadecimal, son distintos.
Los puse en hexadecimal, porque es más fácil entender lo que pasa a nivel de dígitos binarios.

Si realmente el problema fuera el cast que hice a long double, entonces la comparación que puse en el post anterior:

printf("x == 1.1F?? %s", (x == 1.1F)? "SI":"NO");

daría como resultado que "SI", pero en realidad da "NO".

O sea que a nivel interno a ambos valores "el compilador los ve" distintos.

______________

En cuanto a la posibilidad de visualizar valores flotantes en hexadecimal, con printf(),
es una característica que viene estipulada por el estándar C99,
y por lo tanto el GCC 4.7, con la opción de compilación -std=c99, tiene que tenerla incorporada.
Por eso el compilador la tiene, porque es su "obligación" adherirse a algo que ya viene dictado por el estándar.
_________________

En realidad el compilador GCC 4.7 con la opción de compilación -std=c99 incorpora casi todas las reglas que el estándar C99 estipula.
Pero los mismos desarrolladores del compilador dicen que todavía hay detalles que no han podido implementar correctamente.

En el caso de fpclassify(), si te fijás en la definición de esa macro,
vas a ver que la macro realmente intenta detectar números subnormales, para cada tipo de datos, ya sea float, double, long double.

Esto lo hace preguntando por el "tamaño" del dato, mediante un sizeof.
O sea, para saber si un dato X es de tipo "float", pregunta si sizeof(X) == sizeof(float), por ejemplo.

De modo que fpclassify() tendría que distinguir correctamente los casos en que uno tiene un float.

Aún así, no sé si es un bug, o está permitido por el estándar.

_____________

Yo sigo afirmando que la constante 1.1F queda guardada en algún "lugar", no sé cual, con un tamaño de 12 bytes de información, mientras que la variable x tiene sólo 4 bytes.

Es la única explicación que se me ocurre al hecho de que la comparación (x == 1.1F) da falso.

Por el contrario, por ejemplo la comparación (x == (float)(1.1F)) da verdadero.

La constante 1.1F es calculada por el procesador, se guarda el valor en algún lado, con la exactitud de un long double, con 12 bytes, además no le da importancia al sufijo F,.
Cuando le hago un sizeof me da que tiene 4 bytes, y cuando la comparo con x, me da falso.

Es de locos.

Otro detalle. Creo que el compilador directamente reconoce la constanta 1.1F como de tipo "long double".

Esto lo noté al poner a propósito algo erróneo como la operación (1.1F & 1), que me dio error, pero el compilador informa que la causa del error es que "1.1F es long double mientras 1 es int".
¿Y entonces, para qué el sufijo F de 1.1F? ¿No indica eso que la constante es "float"?

La duda que tengo es si, aunque aparentemente esto es un bug del compilador,
¿es de verdad un bug, o es algo que el estándar admite como una posibilidad dentro de las correctas?
Lo mismo me pasa con fpclassify.
¿Es un bug del compilador o no?