Representación del flotador en C

Estaba tratando de entender la representación de punto flotante en C usando este código (tanto float como int son 4 bytes en mi máquina):

 int x = 3; float y = *(float*) &x; printf("%d %e \n", x, y); 

Sabemos que la representación binaria de x será la siguiente.

00000000000000000000000000000011

Por lo tanto, habría esperado que se representara de la siguiente manera

  • Bit de signo (primer bit desde la izquierda) = 0

  • Exponente (bits 2-9 desde la izquierda) = 0

  • Mantisa (bits 10-32): 1 + 2^(-22)+2^(-23)

Conduce a y = (-1)^0 * 2^(0-127) * (1+2^(-22) + 2^(-23)) = 5.87747E-39

Sin embargo, mi progtwig se imprime

3 4.203895e-45

Es decir, y tiene el valor 4.203895e-45 lugar de 5.87747E-39 como esperaba. Por qué pasó esto. ¿Qué estoy haciendo mal?

PS También he impreso los valores directamente desde gdb, por lo que no es un problema con el comando printf.

Los números de punto flotante IEEE con campos exponenciales de todos 0 están ‘desnormalizados’. Esto significa que el 1 implícito delante de la mantisa ya no está activo. Esto permite representar números realmente pequeños. Vea este artículo de wikipedia para más explicación . En tu ejemplo, el resultado sería 3 * 2 ^ -149

-127 en el exponente está reservado para números desnormalizados. Su cálculo es para números normalizados, mientras que su flotador es un flotante desnormalizado.

Los números desnormalizados se calculan utilizando un método similar, pero:

  1. exponente es -126
  2. ya no se supone el bit inicial implícito

Así que esto significa que el cálculo es en cambio:

 (-1)**0*2**(-126)*(2**(-22)+2**(-23)) = 4.2038953929744512e-45 

Lo anterior es python, donde ** significa lo mismo que ^

En detalles, se describe en http://en.wikipedia.org/wiki/IEEE_754-2008. Este estándar asumió que está cambiando la mantisa izquierda hasta ocultar el primer bit de significado (exponente creciente). En su caso, tiene la expresión 1 + 2 ^ (- 23) – luego obtiene la respuesta correcta 4.9..E-32