Division ist nicht wie erwartet

Hallo,

ich versuche einen Wert durch 1000 zu dividieren damit ich anstelle von mA A erhalte.
Der Wert actualCurrent ist zwischen 980 und 2000, die Einheit ist mA. Ich möchte diesen Wert nun aber als Ampere ausgeben.

Im moment sieht das wie folgt aus.

int actualCurrent = 980; // zum testen fix gesetzt


char aCurrent[8];
double str = actualCurrent /1000;
Serial.println(str);

Hier ist der Wert von str im Serial Monitor 0.00
da hätte ich jetzt 0.980 erwartet. Die Zahl ist ja nicht zu hoch für double.

sprintf(aCurrent, "%4.2f", str);
Serial.println(aCurrent);

und das Ergebnis der Formatierung is "?".
auch wenn ich str durch 0.980 ersetze.

sprintf(aCurrent, "%4.2f", 0.980);
Serial.println(aCurrent);

=> ?

Hat mir jemand einen Tipp was ich bei der Division falsch mache?

und warum erhalte ich bei der Formatierung immer ein "?" ?

Danke für eures konstruktive Feedback

Hallo,

mach mal bitte

float str = actualCurrent /1000.0;

Edit:
https://www.arduino.cc/en/Reference/Float
wenn das noch nicht klappt, dann

float str = (float) actualCurrent /1000.0;
1 Like
double str = actualCurrent /1000;

actualCurrent ist ein int (ohne Kommastellen) den dividierst Du durch ein int und erhälst wieder ein int das ohne Kommastellen eben 0 ist. Dann erst wird es in ein float (double) umgewandelt und ist jetzt 0,00 .

float str = actualCurrent /1000.0;
von Doc_Arduino vorgeschlagen ergibt
Durch die Division durch 1000,0 (einer Float-Zahl) ist das Ergebnis auch ein float mit Komastellen und die kommen auch in str an.

Grüße Uwe

ach so, das macht ja auch Sinn.
mit 1000.0 funktioniert es, auch wenn ich actualCurrent mit float caste.

dann entfälllt auch die Formatierung :slight_smile:

danke für den Hinweis.

Hallo Uwe,

vielleicht eine Anfängerfrage. Wann muß man einen Typecast machen und wann nicht? Hier muß man nicht. Darüber stolper ich immer noch hin und wieder und durch testen finde ich dann das richtige.

Es ist stark Compilerabhängig wie das Ergebniss wird. Eigentlich sollte ein Compiler deinen Denkfehler nicht ausbügeln, manche machen es aber. Vorallem Basic-dialekte.

Sie gehen vom Ergebniss aus, das in dem Fall Fliesskomma ist und erzeugen aus allen Int-Zahlen vorher ebenfalls Float bevor sie ans Rechnen gehen. Althergebracht sollte das aber nicht so sein, C macht das jedenfalls nicht. Ich kenne auch keine Weiterentwicklung von C die selbst umstellt.

Pascal zb hat es angemeckert und nicht kompiliert. Da wurde erwartet das alle Typen in einer Berechnung gleich sind. Die Weiterentwicklung von pascal (delphi) konvertiert es inzwischen selbst. Tendenziell scheint es auch dahin zu gehen, das Compiler einem diesen Fehler ausbügeln. Es könnte also sein das in Zukunft auch C und auf C basierende Compiler das selbst umstellen.

Pauschal kann man sagen, das man es nicht falsch macht, wenn man Typen selbst umstellt. Ich mache das auch immer ausserhalb der Formel vor der Berechnung oder benutze sofort Float und konvertiere den Int vom Analogeingang sofort nach dem Einlesen. Aber das ist kein MUSS, es hilft lediglich Flüchtigkeitsfehler zu vermeiden, weil man mal wieder alles hoplahop fertig haben will.

vielleicht eine Anfängerfrage. Wann muß man einen Typecast machen und wann nicht? Hier muß man nicht. Darüber stolper ich immer noch hin und wieder und durch testen finde ich dann das richtige.

Ein Typecast wird gemacht, wenn ein Wert von einem Type in einen Anderen überführt werden muss.
In vielen Fällen macht der Kompiler das problemlos alleine.
z.B. von Byte zu uint32_t

Bei manchen schreit er um Hilfe:
"Hey Programmierer, willst du das wirklich, was ich hier tue?"
Hints und Warnings werden geschüttet.
(Ausführliche Meldungen aktivieren)

Bei anderen Typen verweigert er die Zusammenarbeit.
z.B. bei Zeigern usw.
Handarbeit, ist angesagt!

Also, immer, wenn man die Meinung oder gar das Problem hat, das er sich irrt/versagt, muss man dem Kompiler auf die Sprünge helfen.
Frei nach dem Motto:
Der Programmierer weiß was er erreichen will, und der Kompiler ist kein Telepath.

Tipp:
An unübersichtlichen Stellen..... oder auch generell ...
Wenn du weißt, dass der Kompiler an der Stelle einen impliziten Cast macht, dann schreibe einen expliziten da hin. Der erzeugte Code ist gleich. Aber das Programm/Quelltext zeigt dir was es tut. Es ist Selbstdokumentierend.

Hallo,

verstehe. Vielen Dank an Euch.

printf() geht auf den AVR Prozessoren nicht mit Floats (wurde weggelassen weil es viel Speicher braucht, auch wenn es nicht verwendet wird). Wie kann es sein dass das in so vielen Antworten noch niemand erwähnt hat? :o

Entweder man verwendet print() selbst um die Anzahl der Nachkommastellen alleine anzugeben. Oder dtostrf() zur vollständigen Formatierung.

Wie kann es sein dass das in so vielen Antworten noch niemand erwähnt hat?

Hmmm....

Da kann ich nur für mich selber sprechen:
Mein printf() kann das, wenn ich will.

Serenifly:
printf() geht auf den AVR Prozessoren nicht mit Floats (wurde weggelassen weil es viel Speicher braucht, auch wenn es nicht verwendet wird). Wie kann es sein dass das in so vielen Antworten noch niemand erwähnt hat? :o

Hallo,

wir waren so nett und heben für dich auch noch was auf ... :slight_smile: