Int in float umrechnen

Gast #622454
Lesenswert?

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.
#622479
Lesenswert?

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.
#622514
Lesenswert?

> 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...
Gast #622674
Lesenswert?

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.
#622676
Lesenswert?

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.
Gast #622698
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren