Gleitkommazahl in String konvertieren (Ascii Werte)
-
Hallo ihr!
Von der Uni aus sollen wir eine C-Funktion schreiben, das float's in einen String mit den Ascii Werten der einzelnen Dezimalstellen konvertiert.
Ich hatte eigentlich schon eine Idee zum Auslesen der einzelnen Bit der Gleitkommazahl. Ich wollte mit Hilfe des Bit-And Operators die einzelnen Bits auslesen und in 3 integer speichern. Also das Most significant bit (Vorzeichenbit) in einen Integer, die nächsten 8 Bit (den Exponenten) in einen Integer und die restlichen 23 Bit (die reduzierte Mantisse) in einen dritten Integer. Dann hätte ich mir daraus die Gleitkommazahl berechnet und dann die stellen vor und nach dem Komma in Ascii Werte umgewandelt und in ein Array gespeichert.
Jedoch habe ich jetzt das Problem dass ich & nicht anwenden kann, da ich das nicht bei einem float und einem int anwenden kann.
So hätte das dann ausschauen sollen:float float32 = 1234.5678; unsigned int bitmask_vorzeichen = 0x80000000; unsigned int bitmask_exponent = 0x7F80000; unsigned int bitmask_mantisse = 0x7FFFFF; unsigned int vorzeichen = 0; unsigned int exponent = 0; unsigned int mantisse = 0; vorzeichen = float32 & bitmask_vorzeichen;
Geht aber nicht.
Jetzt bin ich auf der Suche nach einer "neuen" Methode, wie ich Bit für Bit aus einen float auslesen kann.Vielleicht kann mir ja jemand helfen.
Wäre sehr dankbar für jegliche Hinweise.lg
-
Dazu gab es schon einen Thread heute:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-236141-and-highlight-is-matisse.html
P.S.: Selbe Uni?
-
oh man, ich habe das gefühl, hier hängen viele aus deinem seminar rum, diese frage lese ich nun schon zum dritten mal diese woche.
also schau mal, was die anderen schon für antworten haben.
-
fiffy schrieb:
Hallo ihr!
.... Ich wollte mit Hilfe des Bit-And Operators die einzelnen Bits auslesen und in 3 integer speichern. Also das Most significant bit (Vorzeichenbit) in einen Integer, die nächsten 8 Bit (den Exponenten) in einen Integer und die restlichen 23 Bit (die reduzierte Mantisse) in einen dritten Integer. Dann hätte ich mir daraus die Gleitkommazahl berechnet ....
lgder ansatz ist doch super. lass ne einser bitmaske per bitshif drüberwandern, die du &-verknüpfst. mfg
-
So:
long n = *( long* )&float32; vorzeichen = n & bitmask_vorzeichen;
-
danke schon mal für die antworten
David_pb schrieb:
So:
long n = *( long* )&float32; vorzeichen = n & bitmask_vorzeichen;
habs jetzt mit deiner methode und mit der methode mit dem reinterpret_cast probiert. bei beiden schaff ich es das vorzeichenbit und die 23-mantissen bits richtig auszulesen.
mein problem ist aber noch der exponent. der sollte laut meinen (handschriftlichen) berechnungen bei 12,3 folgendermaßen ausschauen 10000010 und danach befinden sich nach der &-Operation mit meiner bitmask_exponent ja eigentlich noch 23 Nullen dahinter. Dadurch wird natürlich die Zahl verändert. Soll ich da jetzt einfach 23 mal nach rechts shiften? Hab ich schon probiert, da kommt dann auch nicht der richtige Wert heraus. (Das ich danach noch den Biaswert abziehen muss, ist mir klar).
-
Deine Maske ist falsch. Die müsste 7F800000h sein. Du kannst aber auch erst 23 Bits nach rechts shiften und dann mit ffh maskieren:
int e = ( ( n >> 23 ) & 0xff ) - 127; int e = ( ( n & 0x7F800000 ) >> 23 ) - 127;
Kommt aufs gleiche raus.
-
David_pb schrieb:
Deine Maske ist falsch. Die müsste 7F800000h sein. Du kannst aber auch erst 23 Bits nach rechts shiften und dann mit ffh maskieren:
int e = ( ( n >> 23 ) & 0xff ) - 127; int e = ( ( n & 0x7F800000 ) >> 23 ) - 127;
Kommt aufs gleiche raus.
hey danke. Ja jetzt wirds richtig ausglesen. War wahrscheinlich ein blöder Abschreibfehler vom Rechner....
Ich werds jetzt probieren fertig zu implementieren und vielleicht meld ich mich dann nochmal
richtig lustig wirds erst wenn ich mit der c-Funktion fertig bin. Dasselbe müssen wir dann nämlich in Assembler auch noch mal programmieren
-
Das in eine Assemblersprache zu übersetzen sollt eigentlich nicht so problematisch sein.
-
ui jetzt habe ich schon das nächste Problem:
Ich habe die Mantisse richtig ausgelesen. Dann habe ich den Einser vorne wieder dazugetan (damit die Mantisse nicht mehr reduziert ist). Dann würde ich gerne 23 mal nach rechts shiften damit ich die "richtige" Mantisse herausbekomme wo ich dann nur noch die Basis mit Exponent multiplizieren muss. Jedoch ist die Mantisse ja eine Kommazahl (1,xxxx). Dann muss ich ja jetzt wieder auf einen float casten oder?
-
Der Explonent gibt an um wieviel Bit das Komma sich nach rechts verschiebt. Dann musst du die Teile links und rechts vom Komma einzeln interpretieren.
-
vor dem shiften mit dem exponenten muss ich ja noch mal shiften.
also ich hab das zahlenbeispiel 12,3die mantisse wär da 1,5375 (12897485 (das ist das was ich herausbekomm nachdem ich die 1 vorne wieder hinzugefügt habe) geteilt durch 2^23, also 23 mal rechtsshift). und erst danach muss ich 1,5375 * 2^3 um wieder auf die 12,3 zu kommen.
kann sein, dass ich jetzt gerade ziemlich auf der Leitung stehe, aber ich weiß gerade echt nicht, wie ich das anstellen soll.
-
Ja, aber leider ist ein rechtsshift hier kein Ersatz und du musst tatsächlich teilen.
-
wenn ich dividier komme ich ja trotzdem auf das ergebnis 1. sollt natürlich 1,5375 sein. Ich weiß einfach nicht, wie ich die 0,5375, die quasi "weggschnitten" werden, doch behalte.
-
Indem du das Ergebnis in ein float schreibst.
-
David_pb schrieb:
Indem du das Ergebnis in ein float schreibst.
ja das ist logisch. nur dann verwende ich ja wieder ein float. und da ich in weiterer Folge ja dann auch noch in Ascii Werte umwandeln soll, ist mir ein integer Wert doch um einiges lieber.
also: mein ziel wär es die zahlen vor dem Komma und die Zahlen nach dem Komma zu trennen und beide als integer abzuspeichern, denn dann kann ich sie ohne Probleme in einen String mit den ASCII Werten umwandeln und als String ausgeben. Die dazugehörige Funktion hab ich schon. Nur muss ich die vor und die nach dem Komma irgendwie trennen...