![]() |
Re: Plötzlich auftretenes Rundungsproblem
Zitat:
* Kaufmänisches Runden: bei x.5 wird immer aufgerundet * "Banker's rounding": bei x.5 wird abwechselnd auf- und abgerundet Delphi verwendet "Banker's rounding". Die Auf- und Abrundungen sollen sich in der Masse gegenseitig aufheben. Kaufmännisches Runden geht so:
Delphi-Quellcode:
Die Art & Weise, mit der die Funktion Round() arbeitet, hängt übrigens von der aktuellen
function CommercialRound(const X: Extended): Int64;
begin Result := Trunc(X); if Frac(Abs(X)) >= 0.5 then Result := Result + Sgn(X); end; Einstellung des FPU Flags-Registers ab. (Wahrscheinlich die Ursache für unterschiedlichem Verhalten von Round auf versch. Rechnern) |
Re: Plötzlich auftretenes Rundungsproblem
Zitat:
Das ganze Problem hängt wohl mit der Floatarithmetik zusammen. In was für einen Datentyp wird denn 3,45*3/0,9 gespeichert... Probier doch mal double oder extended, und kuck was dann bei raus kommt. |
Re: Plötzlich auftretenes Rundungsproblem
Die Funktionsweise von RoundTo kann mit der Prozedur Set8087CW oder der Funktion SetRoundMode gesteuert werden :warn:
|
Re: Plötzlich auftretenes Rundungsproblem
Zitat:
![]() Es kann nämlich durchaus sein, dass du 9.315 hinschreibst, aber gerechnet wird (aus technischen Gründen) u.U. mit soetwas wie 9.314999999956. Dann stimmte das Abrunden wieder. Der Typ "Currency" könnte imho hilfreich bei der Problemlösung sein. Gruss, Fabian |
Re: Plötzlich auftretenes Rundungsproblem
Tut mit leid das ich mich erst jetzt wieder einschalte war total im Stress.
Dir Rechnung sollte lauten 3,45*3*0,9=9,315 anstatt 3,45*3/0,9=9,315. Sorry. Ich konnte mittlerweile die Sache aufklären: Ich rufe an bestimmten Programmpunkten eine externe DLL auf die in CaVo (Visual Object) geschrieben ist und ich rufe nicht FormatFloat direkt auf sondern eine Funktion:
Delphi-Quellcode:
Diese Funktion bekommt den Zahlenwert als Variant übertragen und funktioniert solange ich nicht
function FormStr(const v: Variant; nLen: integer; nDec: integer = 0): string;
var cFormat : string; procedure MakeFormat; begin if nLen > 3 then cFormat := '#,'+cFormat; end; begin if nDec = 0 then begin cFormat := '##0'; MakeFormat; end else begin cFormat := '##0.'+Replicate('0',nDec); nLen := nLen-nDec-1; MakeFormat; end; Result := FormatFloat(cFormat,v); end; die besagte DLL aufgerufen habe. Ich habe noch eine weitere ähnliche Funktion die mit Str arbeitet wo es zum gleichen Problem kommt. Die Lösung liegt zum einen in der Verwendung von Currency-Variablen (wo es möglich ist) zum anderen auf die angesprochenen Funktionen bezogen auf zusätzliche Rundungsfunktionen.
Delphi-Quellcode:
Wie gesagt damit löse ich die Probleme aber interessieren würde es mich doch was die ext. DLL
function FormStr(v: Variant; nLen: integer; nDec: integer = 0): string;
var cFormat : string; procedure MakeFormat; begin if nLen > 3 then cFormat := '#,'+cFormat; end; begin if nDec = 0 then begin cFormat := '##0'; MakeFormat; end else begin cFormat := '##0.'+Replicate('0',nDec); nLen := nLen-nDec-1; MakeFormat; end; case VarType(v) of varCurrency : v := MyRoundC(v,nDec); varInteger : ; else v := MyRound(v,nDec); end; Result := FormatFloat(cFormat,v); end; function MyRoundC(nZahl:Currency;nDec:integer):Currency; var i: integer; begin for i := 1 to nDec do nZahl := nZahl * 10; nZahl := Int(nZahl + iif(nZahl > 0, 0.5, -0.5)); for i := 1 to nDec do nZahl := nZahl / 10; Result := nZahl; end; mit den Variants anstellt. Falls also jemand eine Idee hat ... Ist die Round-Funktion Ok oder gibt es bessere Lösungen ? Grüße Frank |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:09 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