007
25.06.2007, 22:35 Uhr
0xdeadbeef
Gott (Operator)
|
Mal zur Verdeutlichung:
C++: |
#include <stdint.h> #include <stdio.h> #include <float.h>
void print_float(float f) { int i, j; char const *p = (char const *) &f;
for(i = sizeof(float) - 1; i >= 0; --i) { for(j = 7; j >= 0; --j) { printf("%d", p[i] >> j & 1); } putchar(' '); } putchar('\n'); }
int vorzeichen(float f) { char const *p = (char const *) &f;
return p[sizeof(float) - 1] >> 7 & 1; }
int8_t exponent(float f) { #define EXPONENT_BIAS (FLT_MAX_EXP - 1)
unsigned char const *p; int8_t c;
p = (unsigned char const *) &f; c = (int8_t)(((p[sizeof(float) - 1] & '\x7f') << 1) | ((p[sizeof(float) - 2] & '\x80') >> 7)) - EXPONENT_BIAS;
return c;
#undef EXPONENT_BIAS }
float mantisse(float f) { int32_t *p = (int32_t*) &f; int32_t x = *p; int i; float result = 1.0;
for(i = 0; i < FLT_MANT_DIG - 1; ++i) { result += ((x << (33 - FLT_MANT_DIG)) >> (31 - i) & 1) * (1.0 / (2 << i)); }
return result; }
int main(void) { float f = 1500.0;
print_float(f); printf("%d\n", exponent(f)); printf("%d\n", vorzeichen(f)); printf("%lf\n", mantisse(f));
printf("%lf\n", (vorzeichen(f) ? -1.0 : 1.0) * (1 << exponent(f)) * mantisse(f));
return 0; }
|
Auseinandergenommen und wieder zusammengesetzt. Das Vorzeichen ist einfach das erste Bit, die Mantisse halt, wie gesagt, Zweierpotenzen mit negativem Exponenten - also 1/2, 1/4, 1/8 und so weiter. Bemerkenswert ist lediglich der Exponent, der als unsigned int mit 8 bit verstanden wird, von dem aber dann der exponent bias abgezogen wird (Das ist 2^(exponentenbits - 1) - 1, also in diesem Fall 2^7 - 1 = 127), und dass auf die Mantisse noch 1.0 draufgerechnet wird, damit die Rechnung vorzeichen * 2^exponent * mantisse auch funktioniert. -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra Dieser Post wurde am 25.06.2007 um 22:39 Uhr von 0xdeadbeef editiert. |