![]() |
kaufmännisch runden
Hallo,
inder Code-Lib gibt es eine Funktion fürs kaufmännische Runden von shmia: ![]() Leider musste ich fesstellen, dass diese Funktion nicht zuverlässig funktioniert. Im folgenden Beispiel erhalte ich 2 unterschiedliche Werte (einmal wird ab- und einmal wird aufgerundet):
Delphi-Quellcode:
Der zweite Trunc-Befehl in RoundUp() gibt 0 anstatt 1 zurück.
var
x,y : Extended; resx, resy: Extended; begin y := 17.325; resy := RoundX(y,2); //ergibt 17.325 x := ((275 - 27.5) / 100) * 7 ; resx := RoundX(x,2); showmessage(FloatToStr(resx) + ' | ' + FloatToStr(resy)); end; function RoundUp(X: Extended): Extended; begin Result := Trunc(x) + Trunc(Frac(x) * 2); end; function RoundX(const Value:Extended; const nk:Integer): Extended; var multi: Extended; begin multi := IntPower(10, nk); Result := RoundUp(Value*multi) / multi; end; Ursache ist wohl die Genauigkeit von Extended. Wie lässt sich das am besten vermeiden? |
AW: kaufmännisch runden
Seine Funktion funktioniert richtig, aber deine Berechnung rechnet "falsch" => Rundungsfehler
Delphi-Quellcode:
var
x,y : Extended; resx, resy: Extended; begin y := 17.325; resy := RoundX(y, 2); // ergibt 17.325 .... nein, ergibt 17,324999999999999998... // (bzw. 17,324999999999999998265276524023 = 17,325 - 0,00000000000000000173472347597681) x := ((275 - 27.5) / 100) * 7 ; resx := RoundX(x, 2); ShowMessage(FloatToStr(resx) + ' | ' + FloatToStr(resy) + ' | ' + FloatToStr(x - y) + ' = ' + BoolToStr(x = y, True)); end; Zitat:
Delphi-Quellcode:
, läßt sich vermutlich binär nicht genau darstellen.
247.5 / 100
|
AW: kaufmännisch runden
Nicht unbedingt die überwältigende Performance, aber geht:
Delphi-Quellcode:
resx := StrToFloat(Format('%1.*f', [2, x])); Alternativ hilft manchmal auch ein Zwischenschritt über Currency:
Delphi-Quellcode:
resz := FloatToCurr(x);
resz := RoundX(resz,2); |
AW: kaufmännisch runden
Mmmmhh, das blöde ist, das mir aber 17.325 angezeigt werden wenn ich x ausgebe (oder debugge)... Kann man das irgendwo
einstellen? Den weg über Currency habe ich auch schon in Betracht gezogen. Allerdings bin ich mir nicht sicher ob ich mir damit an anderer Stelle Probleme einhandele... |
AW: kaufmännisch runden
Delphi-Quellcode:
:gruebel:
resz := FloatToCurr(x);
resz := RoundX(resz, 2); // dürfte eigentlich Folgendem entsprechen resz := RoundX(x, 4); // FloatToCurr(x); resz := RoundX(resz, 2); |
AW: kaufmännisch runden
Zitat:
Nicht ganz:
Delphi-Quellcode:
kommt eher hin.
resz := RoundX(x, 4); // FloatToCurr(x);
resz := RoundX(resz, 2); |
AW: kaufmännisch runden
Der Trick ist ganz einfach und gilt für alles was mit FLOAT Typen arbeitet (ob Delphi oder SQL Server) und liegt in der Natur des Aufbaus.
Addiere einfach einen ganz kleinen Wert zu deiner Variablen, die Du Runden willst. Also z.B.: x:=Roundx(blablub+0.00000001,2); Danach werden deine Probleme sich lösen:thumb: |
AW: kaufmännisch runden
Nur mal aus Interesse: gibt es einen plausiblen Anwendungsfall dafür, eine Fließkommazahl kaufmännisch zu runden? Mir fällt so spontan nämlich keiner ein...
|
AW: kaufmännisch runden
Praxis: jede Rechnung, Angebot oder Kassenbon ….
|
AW: kaufmännisch runden
Vielleicht will Morphie damit aber auch nur sagen, daß für kaufmännische Anwendungsfälle der Datentyp Currency die bessere Wahl ist?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 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