mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rechnung mit Float (GCC)


Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einen guten Abend,

ich versuche die genaue Temperatur mit einem ds1621 zu ermitteln.
Dazu nutze ich die Formel
temp = data[0] - (1/4) + (slope[0]-counter[0])/(slope[0]);

temp ist vorher als float definiert worden und data[0],slope[0] und
counter[0] haben ganzzahlige Werte.
Dennoch kommt bei der Ausgabe durch sprintf(text,"%f",temp);
und anschließender Übermittelung über UART an den Rechner auf dem
Terminal nur ein '?' an.
Verwende ich sprintf(text,"%d",temp); erhalte ich statt einem '?'
eine 0, in keinem Fall aber den richtigen Wert.
Was mache ich falsch? Wie berechne und übermittle ich solche
Fließkommazahlen?

Gruß Christian

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man einen integer durch einen integer teilt, kommt wieder ein
integer raus... Was du brauchst, sind typecasts:
temp = data[0] - (1/(float)4) +
(slope[0]-counter[0])/((float)(slope[0]));

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du bei den Compileroptionen auch die Unterstützung von float für
printf / sprintf eingeschaltet?

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> temp = data[0] - (1/4) + (slope[0]-counter[0])/(slope[0]);

Zum einem sind da unnötige Klammern drin, zum anderem musst Du eben mit
float rechnen. ;-)

 temp = data[0] - 1.0/4 + (float)(slope[0]-counter[0]) / slope[0];

Immer daran denken: "Punktrechnung vor Strichrechnung" Das gilt auch
für den Compiler.

Der Compiler rechnet immer dann in float, wenn eine Seite der Rechnung
schon in float ist. Aber der Compiler macht auch Punkt-vor-Strich.

D.h. wenn du "1/4" schreibst, macht er eine Integerdivision, bei der
kommt immer 0 raus. Also musst Du "1.0/4" schreiben.

So, das war die erste Teilrechnung, die nach dem Motto "Punkt vor
Strich" vom Compiler durchgeführt wurde.

Nun muss der Compiler "(slope[0]-counter[0])" ausrechnen. Das sind
beides Integerwerte, das kann er also mit Integer machen. Das ist
korrekt.

Dann wird das vorherige Ergebnis durch "slope[0]" geteilt.
"slope[0]" ist aber ein Integer, und der Compiler würde hier also
wieder eine Integer-Rechnung machen. Also musst Du von Hand eine
Argument der Division in float wandeln. Darum das "(float)" vor dem
Klammerausdruck  "(slope[0]-counter[0])". Dadurch wird das Ergebnis
der Integersubtraktion in ein Float gewandelt und anschließend als
float durch slope[0] geteilt.

Zum Schluss hat der Compiler noch ein Interger minus ein Float plus ein
Float zu rechnen. Da mindestes ein Argument ein Float ist, wandelt er
den Integer "data[0]" selber in ein Float um.

Das war's! ;-)

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.