Einzelnen Beitrag anzeigen

raller09

Registriert seit: 7. Nov 2005
37 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

Rundungs-Probleme bei Ausgabe als String

  Alt 15. Feb 2018, 09:39
Moin,

ich habe seit langen mal wieder ein Problem mit der Rundung.
Die grundsätzlichen Probleme mit der Darstellung von Fließkomma-Werten in binärer Form sind mir klar. Auch die interne Datenhaltung verstehe isch (einigermaßen ).
Wenn mir alles klar wäre, würde ich jetzt vermutlich aber nicht fragen:

Ich habe einen Wert aus einer Datenbank, der in eine Delphi-Double-Variable kopiert wird.
Dieser Wert soll dann in einem String ausgegeben werden. Dabei sollen fix 5 Nachkommastellen in der String-Ausgabe genutzt werden.

Delphi-Quellcode:
function Test: string;
var
  lWert: Double;
  lAnzahlNachkommaStellen: integer;
begin
  Result := '';

  lAnzahlNachkommaStellen := 5;
  lWert := 13.727735;

  Result := Format( '%.*f',
                    [ lAnzahlNachkommaStellen,
                      lWert]);
end;

Leider ist es bei mir so, das dabei bei unterschiedlichen Aufrufen unterschiedliche Werte zurückgeliefert werden.
Beim ersten Aufruf wird bei mir aktuell reproduzierbar "13.72773" ausgegeben, bei den folgenden "13.72774". Dazwischen habe ich mit dem Programm einiges gemacht.

Ich habe auch schon einige der anderen Umwandlungen genutzt:
FloatToStr( ...),
FloatToStrF( ...);

diese verhalten sich anscheinend identisch.


Ich denke, in meinem Fall ist es nicht das "Bankers Rounding", dass mir die Werte verstellt. Da müsste dann ja immer der gleiche Wert herauskommen. Auch sage ich nicht, welcher der beiden Werte der richtige sein muss (das hängt ja von der Rundung ab...). Ich benötige nur reproduzierbar gleiche Werte.


Ich habe dann zum testen folgende Funktion probiert:
kaufmännisch runden

Delphi-Quellcode:
  Result := Format( '%.*f',
                    [ RoundX( lWert,
                              lAnzahlNachkommaStellen)]);
Diese verhindert aber das Unterschiedliche Ergebnis bei mehreren Aufrufen nicht.

Erst wenn ich die Rundungs-Funktion mit "lAnzahlNachkommaStellen + 1" aufrufe, scheint es so, dass ich ein reproduzierbares Ergebnis bekomme...
Ist das die korrekte Lösung?
Oder stehe ich ganz woanders auf dem Schlauch...

Zusätzlich: Entspricht die Funktion RoundX aus der Library nicht auch der Funktion "SimpleRoundTo" aus Delphi (bei mir Berlin 10.1 Up2), wenn für "RoundUp" die "Alternative Implementation" genutzt wird? Kann mir jemand den Unterschied erklären? Was ist hier der Unterschied zwischen "Int" und "Trunc", hat die Reihenfolge von "/" und "*" Einfluss auf das Ergebnis?


Vielen Dank
  Mit Zitat antworten Zitat