Einzelnen Beitrag anzeigen

Incocnito

Registriert seit: 28. Nov 2016
210 Beiträge
 
#16

AW: FloatToStrF Rundungsfehler ?

  Alt 3. Feb 2021, 08:47
habe ich etwas gebaut, was das kleinste Diff aufaddiert
darf ich fragen, was du da genau machst?...
Ich ermittel je nach Datentyp die kleinste Differenz, welche beim Aufaddieren den Wert der Variable noch ändert.
Zum Verständnis: Wenn du 4 Bits als Nachkommastellen hättest, könntest der Computer ja
1,00 / 1,0625 / 1,1250 / 1,1875 / 1,2500 / 1,3125 / 1,3750 / 1,4375 / 1,5000 / 1,5625 / 1,6250 / ...
abbilden.
Die Genauigkeit welche ich brauche darf dann natürlich nur entsprechend sein. In dem Fall mit 4 "Nachkomma-Bits"
reicht es nichmal für 1 Nachkommastelle, aber ich kann hier nicht eine Liste für 10 Nachkomma-Bits machen,
damit wir 2 Nachkommastellen zum "Spielen" haben.
Wenn ich '1,4' als Wert bekomme sagt der PC "Ok, 1,3750 ist näher dran als 1,4375, dann speicher ich '1,4' als 1,3750".
Ich rechne in diesem Fall stumpf 0,0625 auf alle ermittelten Ergebnisse.
Wenn ich also den Wert 1,3750 sehe wird daraus 1,4375. Welcher bei der Ausgabe wieder unkritisch wäre.

Ja, wie gesagt, die 4 Bits reichen leider nicht für 1 Nachkommastelle, wie man bei der 1,5000 sieht.
Ich denke mal, dass man 7 Nachkomma-Bits bräuchte (1/128 = 0,0078125) für dieses
Prinzip.
Rechne ich bei 1,5000 die 0,0625 drauf würde gerundet ja tatsächlich 1,6 heraus kommen.
Wenn ich
http://docwiki.embarcadero.com/RADSt...ormate_(Delphi)
richtig lese hat selbst Single 23 Nachkomma-Bits.
Für eine Anwendung die 4 Nachkommastellen braucht ist das also ausreichend.

Anmerkung für die Allwissenden unter euch: Nein, ich lasse die Verschiebung der Mantisse
jetzt mal absichtlich weg und beziehe mich nur auf die Differenz zum Wert 1,0.
Sonst wird das echt zu konpliziert.


...Beim Konvertieren zu einem String, wird ja vermutlich auch eine Differenz aufaddiert.
Hab mich da aber noch nicht tiefer damit beschäftigt.
Der Computer bahandelt hier nur die Darstellung als Text. Das ist nur
numerisch gesehen ein Aufaddieren (oder Abziehen), lass dich davon nicht beirren.

---

Hast du mal versucht auf die Werte, welche du vom Sensor bekommst einfach etwas
drauf zu rechnen? ... Du könntest zum Testen sogar hingehen und sowas machen:
Delphi-Quellcode:
var
  dWert : Single; // oder Double
  sWert : String;
...
  sWert := WertAusSensor();
  dWert := StrToFloatDef(sWert, 0);
  if (dWert <> Trunc(dWert)) then sWert := sWert + '1'; // Nur wenn Nachkommastellen, sonst machst du ja aus "2" eine "21" ;-)
  dWert := StrToFloatDef(sWert, 0);
  ShowMessage(FloatToStrF(dWert, ffFixed, 6, 4));
Ob man jetzt stiltechnisch sagt "ich mache StrToFloat() und fange die Exception ab/nicht ab" oder
ob man für den Default-Wert einen unrealistischen Wert nimmt und eine Meldung ausgibt,
falls dieser Wert dann heraus kommt oder man direkt mit "TryStrToFloat" arbeitet,
kann sich meinetwegen jeder selbst aussuchen.
Für deinen speziellen Fall dürfte das so aber reichen.

Anmerkung: Da es je nach Anwendungsfall anders gehandhabt werden muss, können Programmiersprachen
das nicht "von sich aus korrigieren". Delphi bietet allerdings mit dem Datentyp "Currency" eine
gute Möglichkeit solche Fehler mit Hausmitteln einfach zu bekämpfen, wenn man 4 Nachkommastellen
und weniger braucht. Leider reicht das für deinen Fall hier nicht.

Melde dich, ob du mit meinem Ansatz das Problem beheben konntest.

LG Incocnito
  Mit Zitat antworten Zitat