Forum: Mikrocontroller und Digitale Elektronik Int in float umrechnen


von carola (Gast)


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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.

von Johannes M. (johnny-m)


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...

von carola (Gast)


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.

von Karl H. (kbuchegg)


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.

von carola (Gast)


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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Willi W. (williwacker)


Lesenswert?

>   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
Noch kein Account? Hier anmelden.