Seltsames Verhalten bei float to int

Hallo,

ich bin immer noch blutiger Anfänger, verwende die Arduino IDE 1.8.10 und habe folgendes mir nicht erklärbare Verhalten entdeckt:

Abgesehen vom üblichen drumherum sieht mein Programm wie folgt aus:

float battChargePower;
int battint;

battChargePower = 44.00

Serial.println (battChargePower);
battint = battChargePower;
Serial.print (battint);

Ausgabe ist:
44.00
44

Gebe ich battChargePower den Wert 45 oder 46 (mehr nicht getestet), so lautet die Ausgabe

45.00
44

bzw.

46.00
45

Warum ist das so?

Edit: Hardware ist ein Wemos D1 mini

Bitte zeige den kompletten Code, damit man ihn auf dem eigenen Rechner testen kann. Fasse ihn in Code-Tags, damit er besser lesbar ist.

Gruß

Gregor

Wahrscheinlich weil 45.00 nicht genau 45.00 ist sondern 44.9999999.
Mach mal Serial.println (battChargePower,8);

grüße Uwe

Hi

float hat die unangenehme Eigenschaft, daß Das seeehr genau ist - aber eben nicht ganz genau.
Wenn Du nun der Float-Variable den Wert 45 zuweist, wird Da intern wohl 44.9999999999999999925635452 draus (oder Ähnlich).
Für INT werden einfach nur die Nachkommastellen abgeschnitten - über bleibt 44.

Bei der 44 wird's 44.00011011023452 sein (wieder 'oder Ähnlich')

MfG

uwefed:
Wahrscheinlich weil 45.00 nicht genau 45.00 ist sondern 44.9999999.

Sollte eigentlich bei diesen Zahlen noch keine Rolle spielen:

https://www.h-schmidt.net/FloatConverter/IEEE754de.html

Mach mal Serial.println (battChargePower,8);

Und das wird auch korrekt angezeigt

Wobei ich das Problem generell nicht bestätigen kann. Bei mir geht das so wie man es erwartet

Ok,

warum 45 nicht genau 45 ist, ist mir nicht klar.
Das Problem trat auf, weil ich von einem Wert, z.B. 123.45 jeweils die Vor- und Nachkommastellen als Integer benötige - und zwar genau, nicht ungefähr 45...
Wie stelle ich das an?

Der Versuch war komplett:

#include "settings.h"

float battChargePower;
int battint;

void setup() {
Serial.begin(115200);
}

void loop() {

battChargePower = 123.45;
      
battint = battChargePower;                              //Vorkommastellen = battint = 123
Serial.println (battint);
      
battChargePower = battChargePower - battint;   //123.45 - 123 = 0.45
Serial.println (battChargePower);
      
battChargePower = battChargePower * 100.0;    //0.45 * 100 = 45.00
Serial.println (battChargePower);
      
battint = battChargePower;                              //Nachkommastellen = battint = 45
Serial.println (battint);
delay(5000);
}

warum 45 nicht genau 45 ist, ist mir nicht klar.

Wenn du dich kundig machst, wie Float Zahlen in der binären Reprasentation aussehen, dann wird dir das klarer.

evtl hilfreich round() rint()

Mit

battint = rint(battChargePower);

vor dem delay hat es zumindest mit 123.45 funktioniert - jetzt mal andere Werte testen.

Wieso hast du das nicht gleich gesagt. Das ist etwas völlig anderes!

123.45 ist eigentlich 123.4499969482421875

Siehe mein Link. Und lies vielleicht mal etwas mehr über IEEE-754. Vereinfacht gesagt hast du den Fall dass eine unendliche Anzahl an Zahlen mit einer auf 32 Bit begrenzten Anzahl von Werten dargestellt werden müssen. Dabei kommst es zu Rundungsfehlern weil es nicht für alle Zahlen eine passende Bit-Darstellung gibt

Als Lösung musst vor dem Cast auf Integer richtig runden