Hallo, ich möchte mit Hilfe einer C-Funktion eine 2er-Komplement-Zahl in eine float-Zahl umrechnen. Ich habe es mit folgender Funktion versucht : float ZweierKomToFloat(int Zahl) { xdata int Hilfsvariable, Vorzeichen; xdata float Ergebnis; Hilfsvariable = Zahl; Hilfsvariable >>= 15; if(Hilfsvariable == 0) { Ergebnis = Zahl; return(Ergebnis); } Vorzeichen = 0x10000000000000000000000000000000; Hilfsvariable = Zahl; Hilfsvariable -= 1; Hilfsvariable =~ Hilfsvariable; Hilfsvariable += Vorzeichen; Ergebnis = (float)Hilfsvariable; return(Ergebnis); } Bei der Berechnung des Wertes und der Dimension funktioniert auch alles, nur das Vorzeichen wird nicht korrekt dargestellt. Hat jemand eine Idee, wie ich das lösen kann? Ich benutze den C51-Compiler von Keil (µVision3). Danke schonmal für die Hilfe.
Was ist falsch an
1 | float ZweierKomToFloat(int Zahl) |
2 | {
|
3 | return Zahl; |
4 | }
|
Ich denke mal die Annahme, dass dein Compiler 2-er Komplement für integer benutzt, ist nicht so weit hergeholt.
Im übrigen ergibt sich bei 2-er Komplement Darstellung das Vorzeichenbit ganz von alleine. Vorzeichenwechsel im 2-er Komplement: * alle Bits umdrehen * 1 addieren Also:
1 | float ZweierKomToFloat(int Zahl) |
2 | {
|
3 | xdata int Hilfsvariable; |
4 | xdata float Ergebnis; |
5 | |
6 | Hilfsvariable = Zahl; |
7 | Hilfsvariable >>= 15; |
8 | |
9 | // Zahl ist schon positiv
|
10 | |
11 | if(Hilfsvariable == 0) |
12 | {
|
13 | Ergebnis = Zahl; |
14 | return(Ergebnis); |
15 | }
|
16 | |
17 | // Zahl ist negativ
|
18 | // Zahl erst mal positiv machen
|
19 | Hilfsvariable = Zahl; |
20 | Hilfsvariable =~ Hilfsvariable; |
21 | Hilfsvariable += 1; |
22 | |
23 | Ergebnis = (float)Hilfsvariable; |
24 | Ergebnis *= -1.0f; |
25 | |
26 | return Ergebnis; |
27 | }
|
Aber wozu das jemand machen möchte ist mir rätselhaft. Ein simples
1 | Hilfsvariable = -Hilfsvariable; |
zwingt den Compiler sich um das 2-er Komplement anzunehmen und das Vorzeichen zu wechseln.
> Vorzeichen = 0x10000000000000000000000000000000;
Das rechts vom "=" ist ein 128-Bit-Wert. Den wirst Du nie in einen
16-Bit-Integer reinbekommen! Nach der Zuweisung wird "Vorzeichen" immer
0 sein. Was Du meinst, ist vermutlich ein "b" anstelle des "x". Dann
muss das ganze aber immer noch um die Hälfte gekürzt werden, da Integer
bei 8-Bit-µCs i.d.R. 16 Bit breit sind und nicht 32...
Danke für die Hilfe, ich habe die Version mit Ergebnis = (float)Hilfsvariable; Ergebnis *= -1.0f; verwendet und es klappt jetzt. Ich habe das umgewandelt, da bei den weiteren Berechnungen ein Vorzeichenproblem aufgetreten ist. Ich wollte die Umwandlung machen, um zu überprüfen, an welcher Stelle der Fehler liegt. @Johannes Habe mich bei den Nullen verzählt, aber da ich jetzt die oben angegebene Lösung verwende benötige ich diese Variable nicht mehr.
carola wrote: > Danke für die Hilfe, ich habe die Version mit > Ergebnis = (float)Hilfsvariable; > Ergebnis *= -1.0f; > verwendet und es klappt jetzt. Ich versteh immer noch nicht, warum du nicht einfach Ergebnis = Zahl; machst. Also: Einfach zuweisen und der Compiler kümmert sich um die Details. Ist doch das Naheliegenste.
Das habe ich ja am Anfang gemacht, da ich die einfachste Lösung gesucht habe. Allerdings habe ich damit dann Vorzeichenfehler bei der weiteren Berechnung gehabt. Deswegen habe ich nach einer Lösung gelöst, wo ich genau sehe was in den Zwischenschritten gerechnet wird. Wenn der Fehler schließlich an einer anderen Stelle liegt, kann ich es ja wieder ändern.
Ich meine
1 | float IntToFloat( int Zahl ) |
2 | {
|
3 | return Zahl; |
4 | }
|
Ist für mich das absolut Naheliegenste. Die Lösungen die bisher aufgetaucht sind, machen alle mitsammen auch nichts anderes als dieser simple 3-Zeiler.
> Ergebnis = (float)Hilfsvariable; > Ergebnis *= -1.0f; Multiplikationen auf dem 51er sind sehr teuer, wie wäre es mit: Ergebnis = -(float)Hilfsvariable;
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.