mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Int in float umrechnen


Autor: carola (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist falsch an
float ZweierKomToFloat(int Zahl)
{
  return Zahl;
}

Ich denke mal die Annahme, dass dein Compiler 2-er Komplement
für integer benutzt, ist nicht so weit hergeholt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
float ZweierKomToFloat(int Zahl)
{
  xdata int Hilfsvariable;
  xdata float Ergebnis;

  Hilfsvariable = Zahl;
  Hilfsvariable >>= 15;

  // Zahl ist schon positiv

  if(Hilfsvariable == 0)
  {
    Ergebnis = Zahl;
    return(Ergebnis);
  }

  // Zahl ist negativ
  // Zahl erst mal positiv machen
  Hilfsvariable = Zahl;
  Hilfsvariable =~ Hilfsvariable;
  Hilfsvariable += 1;

  Ergebnis = (float)Hilfsvariable;
  Ergebnis *= -1.0f;

  return Ergebnis;
}

Aber wozu das jemand machen möchte ist mir rätselhaft. Ein
simples
  Hilfsvariable = -Hilfsvariable;
zwingt den Compiler sich um das 2-er Komplement anzunehmen
und das Vorzeichen zu wechseln.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: carola (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: carola (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine
float IntToFloat( int Zahl )
{
  return Zahl;
}

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.

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   Ergebnis = (float)Hilfsvariable;
>   Ergebnis *= -1.0f;

Multiplikationen auf dem 51er sind sehr teuer, wie wäre es mit:

Ergebnis = -(float)Hilfsvariable;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.