![]() |
AW: SimpleRoundTo
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,
Zitat:
Delphi-Quellcode:
Damit: Trunc(1017.99999999999998) = 1017.
var
f : Double; a, b, c : Extended; begin a := 0.55; b := 18.5; f := IntPower (10, -2); c := a * b; // 10.175 in den Lokalen Variablen, 10.175 in Überwachte Ausdrücke c := c / f; // 1017.5 in den Lokalen Variablen, aber 1017.49999999999998 in Überwachte Ausdrücke (und damit wird gerechnet) c := Trunc (c + 0.5) * f; end; Diese Variante
Delphi-Quellcode:
Gruß
var
f : Double; a, b, c : Double; begin a := 0.55; b := 18.5; f := IntPower (10, -2); c := a * b; // 10.175 in den Lokalen Variablen, 10.1750000000000007 in Überwachte Ausdrücke c := c / f; // 10.175 in den Lokalen Variablen, 10.175 in Überwachte Ausdrücke c := Trunc (c + 0.5) * f; // 10.18 in den Lokalen Variablen, aber 10.1799999999999997 in Überwachte Ausdrücke Caption := FloatToStr (c) // gibt 18,18 aus hier richtet es FloatToStr end; |
AW: SimpleRoundTo
Delphi-Quellcode:
Das ist ja in diesem Fall auch völlig korrekt, weil der Fehler von 3E-16 innerhalb der maximal mit Double erreichbaren Genauigkeit liegt. FloatToStr ist, soweit ich weiß, für eine Genauigkeit von 16 Ziffern ausgelegt, also etwa der Auflösung von Double.
c := Trunc (c + 0.5) * f; // 10.18 in den Lokalen Variablen, aber 10.1799999999999997 in Überwachte Ausdrücke
Caption := FloatToStr (c) // gibt 18,18 aus hier richtet es FloatToStr Der Kern des Fehlers könnte in den verschiedenen Rundungsalgorithmen des Debuggers und von SimpleRoundTo liegen. Der Debugger verwendet ja vermutlich das bankersrounding, während das Programm überwiegend SimpleRoundTo verwendet. Dadurch werden die Werte im Debugger anders dargestellt, als programmintern gerechnet wird und es kommt vielleicht vermeintlich zu einem falschen Ergebnis. Bei den überwachten Ausdrücken wird erfreulicherweise anscheinend der Gleitkommawert komplett dekodiert und nicht ein bereits gerundeter Wert. Es wäre spannend mit dieser Erkenntnis nochmal Mult3 zu debuggen. MrSpock führt ja aus, dass bei Ihm die Funktion DecimalRoundExt schließlich den Fehler beseitigt hat. Diese Funktion unterscheidet sich von SimpleRoundTo im Wesentlichen dadurch, dass vor dem Runden ein Fehleraufschlag dazu addiert wird. Das bedeutet aber lediglich, dass ein wenig früher nach oben gerundet wird (statt ab 0,005 dann schon ab 0,004999..). Das ist aber nur sinnvoll, wenn man der Auffassung ist, dass es in der vorherigen Berechnung einen konstanten Fehler nach unten gibt (also das Ergebnis von Mult3 stets eher zu klein ist) und keinen zufällig verteilten Fehler. Warum sollte das Ergebnis der Division durch 1E9 immer nach unten vom korrekten Wert abweichen? Bei Gleitkommaberechnungen würde ich aber normalerweise von einem zufällig verteilten Fehler ausgehen (u.a. eben wegen des voreingestellten bankersroundings). |
AW: SimpleRoundTo
Ich nutze DecimalRoundExt nicht mit dem Standardwert als "control", sondern mit drHalfUp. Damit habe ich den Effekt, den ich möchte. Zumindest in den Testfällen, die ich benutzt habe. Jetzt muss ich noch die Reaktion des Kunden abwarten, ob im operationellen Einsatz auch kein Cent-Fehler mehr auftritt.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz