Interne Zahlendarstellung Typ float
-
Hallo Leute!
Irgendwer hat im Internet dieses kleine prog reingestellt, das die
Zahlendarstellung von Fließkommazahlen typ float ermöglicht.
Ich habe nur eine kleine Funktion dazugestellt, um das ganze mal
auch binär zu sehen.
Einen Schönheitspreis will ich dafür nicht gewinnen, zum
experimentieren reicht es aber:/* Stellt float-Variablen als Fließkomma, hexadezimal, dezimal und binaer dar. */ #include <stdio.h> #include <stdlib.h> void chartobin(unsigned int letter, char wort[]) { unsigned int slei, dum, testwert; if ((letter < 0) || (letter > 255)) goto finito; /* Ininitalisert die 8 Binärstellen mit Null */ for (slei = 0; slei <= 11; slei++) wort[8] = '\0'; for (slei = 0; slei <= 7; slei++) { testwert = 128 >> slei; /* Bit7(128dez) ist auf Char-Nr.0 */ dum = letter & testwert; if (dum != 0) wort[slei] = '1'; else wort[slei] = '0'; } finito: ; } int main(void) { int i; union { float d; unsigned char c[4]; } a; char binzahl[20]; a.d = 0.001273; printf("Dargestellte Zahl: %f\n", a.d); printf("Hexadezimal:\n"); for (i=3; i>= 0; i--) printf("%02x ", a.c[i]); printf("\n\nDezimal:\n"); for (i=3; i>= 0; i--) printf("%02d ", a.c[i]); printf("\n\nBinaer:\n"); for (i=3; i>= 0; i--) { chartobin(a.c[i], binzahl); printf("%s ", binzahl); } a.d = -0.001273; printf("\n\nDargestellte Zahl: %f\n", a.d); printf("Hexadezimal:\n"); for (i=3; i>= 0; i--) printf("%02x ", a.c[i]); printf("\n\nDezimal:\n"); for (i=3; i>= 0; i--) printf("%02d ", a.c[i]); printf("\n\nBinaer:\n"); for (i=3; i>= 0; i--) { chartobin(a.c[i], binzahl); printf("%s ", binzahl); } return 0; }
Ausgabe wie folgt:
Dargestellte Zahl: 0.001273 Hexadezimal: 3a a6 da cb Dezimal: 58 166 218 203 Binaer: 00111010 10100110 11011010 11001011 Dargestellte Zahl: -0.001273 Hexadezimal: ba a6 da cb Dezimal: 186 166 218 203 Binaer: 10111010 10100110 11011010 11001011
-
Ich nehme da gerne http://www.h-schmidt.net/FloatConverter/IEEE754.html
gcc schrieb:
C:\Users\..\main.c|12|warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]|
(Das mit dem goto ist doch Vorsatz)
-
Hallo DrikB!
Sorry für das goto.
Mea maxima culpa!
void chartobin(unsigned int letter, char wort[]) { unsigned int slei, dum, testwert; if ((letter >= 0) && (letter <= 255)) { /* Ininitalisert die 8 Binärstellen mit Null */ for (slei = 0; slei <= 11; slei++) wort[8] = '\0'; for (slei = 0; slei <= 7; slei++) { testwert = 128 >> slei; /* Bit7(128dez) ist auf Char-Nr.0 */ dum = letter & testwert; if (dum != 0) wort[slei] = '1'; else wort[slei] = '0'; } } }
Besser so?
Die Funktion habe ich mir geschrieben, wei sie keine Vornullenunterdrückung hat.
Ist noch von meiner alten Zeit hängen geblieben.
Danke übrigens für die Seite. Ich werde sie mir merken. Ein Rätzel ist
es mir übrignes, wie man die Zahl 2546379 in 1.3035520315170288
umwandelt. Ebenso, wie der Exponent 2^(-10) aus der Zahl 117 gebildet wird.
Wenigstens zeigt die Seite, das ich die Bytes richtig
ausgelesen habe.Da ist noch eine Frage DrikB:
Wenn ich eine float-Variable in einer Datei abspeichern will, im
IEEE 754-Format, wäre dann Reihenfolge des kleinen Progs richtig, also
zuerst das Byte mit dem Vorzeichenbit, also
zuerst 3a dann a6, da und schließlich cb?Nun das geringfügig überarbeitete prog:
/* Stellt float-Variablen als Fließkomma, hexadezimal, dezmal und binaer dar. */ #include <stdio.h> #include <stdlib.h> void chartobin(unsigned int letter, char wort[]) { unsigned int slei, dum, testwert; if ((letter >= 0) && (letter <= 255)) { /* Ininitalisert die 8 Binärstellen mit Null */ for (slei = 0; slei <= 11; slei++) wort[8] = '\0'; for (slei = 0; slei <= 7; slei++) { testwert = 128 >> slei; /* Bit7(128dez) ist auf Char-Nr.0 */ dum = letter & testwert; if (dum != 0) wort[slei] = '1'; else wort[slei] = '0'; } } } int getvorzeichenbit(unsigned char lbyte) { int vz = 0; if ((lbyte & 128) != 0) vz = 1; else vz = 0; return vz; } short getleftword(unsigned char intteile[]) { short erge = 0; erge += intteile[3] << 8; erge += intteile[2]; return erge; } int getmantisse(unsigned char intteile[]) { int erge = 0; erge += intteile[2] << 16; erge += intteile[1] << 8; erge += intteile[0]; erge &= 8388607; return erge; } void intzuchar(int zuza, unsigned char (*intteile)[]) { (*intteile)[0] = zuza & 255; (*intteile)[1] = (zuza & (255 << 8)) >> 8; (*intteile)[2] = (zuza & (255 << 16)) >> 16; (*intteile)[3] = (zuza & (255 << 24)) >> 24; } int main(void) { int i, manti, vzbt; float fzahl; short hoza; union { float d; unsigned char c[4]; } a; char binzahl[20]; unsigned char intteile[4]; printf("Bitte eine float-Zahl eingeben: "); scanf("%f", &fzahl); a.d = fzahl; printf("Dargestellte Zahl: %f\n", a.d); printf("Hexadezimal......: "); for (i=3; i>= 0; i--) printf("%02x ", a.c[i]); printf("\n\nDezimal..........: "); for (i=3; i>= 0; i--) printf("%02d ", a.c[i]); printf("\n\nBinaer...........: "); for (i=3; i>= 0; i--) { chartobin(a.c[i], binzahl); printf("%s ", binzahl); } hoza = getleftword(a.c); hoza >>= 7; hoza &= 255; vzbt = getvorzeichenbit(a.c[3]); printf("\nVorzeichenbit...: %d", vzbt); printf("\nExponent dezimal: %d", hoza); manti = getmantisse(a.c); printf("\nMantisse dezimal: %d", manti); chartobin(hoza,binzahl); printf("\n\nExponent binaer : %s", binzahl); printf("\nMantisse binaer : "); intzuchar(manti, &intteile); for (i=2; i>= 0; i--) { chartobin(intteile[i], binzahl); printf("%s ", binzahl); } a.d = fzahl * -1; printf("\nDargestellte Zahl: %f\n", a.d); printf("Hexadezimal......: "); for (i=3; i>= 0; i--) printf("%02x ", a.c[i]); printf("\nDezimal..........: "); for (i=3; i>= 0; i--) printf("%02d ", a.c[i]); printf("\n\nBinaer...........: "); for (i=3; i>= 0; i--) { chartobin(a.c[i], binzahl); printf("%s ", binzahl); } hoza = getleftword(a.c); hoza >>= 7; vzbt = getvorzeichenbit(a.c[3]); printf("\nVorzeichenbit...: %d", vzbt); hoza &= 255; printf("\nExponent dezimal: %d", hoza); manti = getmantisse(a.c); printf("\nMantisse dezimal: %d", manti); chartobin(hoza,binzahl); printf("\n\nExponent binaer : %s", binzahl); printf("\nMantisse binaer : "); intzuchar(manti, &intteile); for (i=2; i>= 0; i--) { chartobin(intteile[i], binzahl); printf("%s ", binzahl); } return 0; }
Für die "Null" die zuviel angezeigt wird beim höchstwertigen Byte der
Mantisse möchte ich mich entschuldigen. aber ich bin zu faul, um die
Funktion chartobin extra nur für dieses Byte umzuschreiben.
-
rustyoldguy schrieb:
unsigned int letter; ... if ((letter >= 0) || (letter <= 255))
Diese Bedingung ist immer wahr.
Und das meldet dir auch der Compiler, wenn du die (richtigen) Warnungen aktivierst.
^(Weiter habe ich nicht geschaut)^Die Reihenfolge hängt von der Endianess des Systems ab.
-
Und was lernt uns das?
-
Stimmt, riesen Schlamperei von mir, wurde bereits korrigiert.
Eine Seite mit Berechnungsbeispielen habe ich auch gefunden.
Eine weitere Betrachtung meinerseits erübrigt sich.
Das Rad muß nicht noch einmal erfunden werden.