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


von Christian Schreiber (Gast)


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

von Jan (Gast)


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]));

von thkais (Gast)


Lesenswert?

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

von Unbekannter (Gast)


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! ;-)

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.