Solución:
Mi consejo es ceñirse a la regla 0 y no rehacer lo que ya hacen las bibliotecas estándar, si esto es suficiente. Mire math.h (cmath en C ++ estándar) y funciones frexp, frexpf, frexpl, que rompen un valor de punto flotante (double, float o long double) en su parte de significando y exponente. Para extraer el signo del significado, puede usar signbit, también en math.h / cmath, o copysign (solo C ++ 11). Algunas alternativas, con semánticas más ligeras, son modf e ilogb / scalbn, disponibles en C ++ 11; http://en.cppreference.com/w/cpp/numeric/math/logb los compara, pero no encontré en la documentación cómo se comportan todas estas funciones con +/- inf y NaNs. Finalmente, si realmente desea usar máscaras de bits (por ejemplo, necesita desesperadamente saber los bits exactos, y su programa puede tener diferentes NaN con diferentes representaciones, y no confía en las funciones anteriores), al menos haga que todo sea independiente de la plataforma utilizando las macros en float.h / cfloat.
Creo que es mejor usar gremios para hacer los yesos, está más claro.
#include <stdio.h>
typedef union {
float f;
struct {
unsigned int mantisa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} parts;
} float_cast;
int main(void) {
float_cast d1 = { .f = 0.15625 };
printf("sign = %xn", d1.parts.sign);
printf("exponent = %xn", d1.parts.exponent);
printf("mantisa = %xn", d1.parts.mantisa);
}
Ejemplo basado en http://en.wikipedia.org/wiki/Single_precision
Descubra el formato de los números de punto flotante utilizados en la CPU que admite directamente el punto flotante y divídalo en esas partes. El formato más común es IEEE-754.
Alternativamente, puede obtener esas partes usando algunas funciones especiales (double frexp(double value, int *exp);
y double ldexp(double x, int exp);
) como se muestra en esta respuesta.
Otra opción es usar %a
con printf()
.