www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik dtostrf ieee754 Ausgabefehler?


Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich versuche mich gerade in C-Programmierung und probiere z.Z. dtostrf 
und dtostre aus. Wenn ich den µC rechnen lasse und das Ergebnis auf den 
LCD ausgebe haut das ja hin:
  float f1 = -1.25;
  float f2 = 2.5;
  float f = f1 * f2;
  char s1[20];
  lcd_string(dtostrf (f,6,2,s1));  //Ausgabe z.B.: 123.34
  lcd_string(dtostre (f,s2,3,1));  //Ausgabe z.B.: 1.2334e+02

Das Ergebnis auf dem LCD lautet 3.125 und ist somit korrekt.

Im nächsten Schritt habe ich aus Wikipedia einen Gleitkommawert (Single 
Precision) nach IEEE754 als Hew _Wert eingegeben:

Zahl = +11,25 = 0b01000001001101000000000000000000 = 0x41340000

und wollte dann die korrekte Zahl auf dem LCD sehen aber raus kam:

1093926792,14

Der Codeschnipsel dazu:
  float f1 = 0x41340000
  char s1[20];
  lcd_string(dtostrf (f1,6,2,s1));  //Ausgabe z.B.: 123.34
  lcd_string(dtostre (f1,s1,3,1));  //Ausgabe z.B.: 1.2334e+02

Kann mir das bitte jemand erklären?

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Z. wrote:

> Das Ergebnis auf dem LCD lautet 3.125 und ist somit korrekt.

Du hast noch viel zu lernen :-)

> Der Codeschnipsel dazu:
> [avrasm]
>   float f1 = 0x41340000

Äh, nein.
Damit setzt du nicht die Bitrepräsentierung auf 0x41340000
sondern du weist dem float die Zahl 1093926912 zu.

Das ist grundsätzlich nichts anderes, als wie wenn du
schreiben würdest:

   float f = 3;

um f den Wert 3 zu geben. Nur dass du deine Zahl als Hex-Zahl
formuliert hast.

> und wollte dann die korrekte Zahl auf dem LCD sehen aber raus kam:
1093926792,14

Zurück zu der Anmerkung von oben (von wegen lernen und so)

Du hast zugewiesen:              1093926912
und der float enthielt danach:   1093926792,14

Siehst du den Unterschied? Mit float erhältst du Fliesskommazahlen
die ca 6 bis 7 signifikante Stellen aufweisen. In deinem Fall
ist die 7-te Stelle (links zu zählen anfangen) sogar noch korrekt,
aber alles was rechts davon kommt, ist pure Erfindung (man kann
natürlich erklären warum das so ist, würde jetzt aber zu weit
führen). Und genau das meine ich mit: du musst noch viel lernen
wenn du im Zusammenhang mit float von korrekt sprichst. Diese
6 signifikanten Ziffern (die weniger werden wenn du dann auch noch
mit den floats rechnest), können einem nämlich den ganzen Tag
versauen. :-)

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ersteinmal Danke für die schnelle Antwot zu so später Stunde!

Ja da oben habe ich noch das Minus vergessen, die Abneigung gegen das 
neg. Vorzeichen ist wohl in meinen Kontoauszügen zu suchen :)

Das zweite leuchtet mir ein, aber ich wußte mir nicht anders zu helfen. 
Kann ich das Bsp. aus Wikipedia, angenommen ich habe nur die Zahl im 
IEEE754 Format, denn mit dieser Funktion in der Form +11,25 ausgeben?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hexadezimale Gleitkommazahlen kann man mit 0x1324p56 oder sowas
eingeben, aber ich bin mir mit der tatsächlichen Darstellung der
Bits im Moment nicht ganz sicher.  Probier sowas besser auf einem
Hostcomputer-C aus statt auf dem Controller.

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

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal die Umkehrung probieren:
float Zahl zuweisen und danach die Byte-Repräsentierung
begutachten. Wenn sie mit der Veröffentlichen übereinstimmt,
dann kann man das dann auch umgekehrt mache.
int main()
{
  union conv {
    float f;
    unsigned char b[4];
  } convert;

  convert.f = 11.25;

  for( int i = 0; i < 4; ++i )
    printf( "%x", convert.b[i] );
}

oder welche Möglichkeiten du auch immer hast um ein
Byte auszugeben.

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mich jetzt erst mal demütig mit C Literatur eingedeckt.

Muss mir auch erst mal die Geschichte mit den Strukturen richtig zu 
Gemüte führen um zu verstehen was die union macht und C generell.
Ist es richtig das der float Wert als selbiger übergeben wird und dann 
Byteweise als char ausgelesen wird?

Ich habe das mal auf dem LCD ausgegeben und die Bytes sind zwar invers 
angeordnet aber es stimmt!!!

Mein Ziel ist es über RS485 Modbus RTU eine float Zahl im IEEE754 Format 
intern im µC weiterzuverarbeiten und wenn ich die Union wie 
vorgeschlagen umgekehrt laufen lasse müsste das ja passen...

Werde ich jetzt mal ausprobieren.

Auf jeden Fall vielen vielen Dank an Euch beide, werde dann mal meinen 
Fortschritt hier reinschreiben. Die Version mit der Eingabe in der Form 
0x1324p56 werde ich auch noch mal ausprobieren.

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.