AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Rundungsproblem mit MSSQL
Thema durchsuchen
Ansicht
Themen-Optionen

Rundungsproblem mit MSSQL

Ein Thema von gmc616 · begonnen am 8. Apr 2021 · letzter Beitrag vom 8. Apr 2021
Antwort Antwort
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
724 Beiträge
 
Delphi XE5 Professional
 
#1

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 15:30
Hallo gmc616,
Du solltest anstelle von nPow := power(10,2); besserConst nPow = 100 schreiben, denn power(..) arbeitet mit Logarithmen, wodurch automatisch Rundungsfehler in den letzten Stellen entstehen.

Bis Du Dir sicher, daß der Wert von Netto_Org genau 206,5 ist? Ein winziger Rundungsfehler bei der internen binären Darstellung z.B. von 206,4999999999 würde schon dazu führen, daß korrekt auf 245,73 abgerundet wird. Kannst Du den aktuellen Wert Netto_Org auch 18 Stellen ausdrucken lassen? Im Debugger sieht man oft nur gerundete Werte.

Welchen Datentyp hat Netto_Org in Deiner Datenbank?

Gruß, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
724 Beiträge
 
Delphi XE5 Professional
 
#2

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 15:44
Der Datentyp Currency ist allerdings keine „Allzweckwaffe“, denn die seine festen 4 Nachkommastellen sind nur bei Addition und Subtraktion von Währungseinheiten (mit max. 4 Nachkommastellen!) exakt. Bei Multiplikation, Division und sonstigen transzendenten Operationen pflanzen sich die Rundungsfehler in hintere Nachkommastellen fort und das Problem bleibt bestehen.

Wenn Du nPow := power(10,2); anstellen einer Konstanten-Deklaration verwenden willst, dann solltest Du eine einfache Funktion Function IntegerPotenz(Basis, Potenz: Integer): Integer; schreiben, welche die Basis (hier: 10) n-mal (her: 2-mal) miteinander multipliziert. Dann bist Du flexibler.
Gruß, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
724 Beiträge
 
Delphi XE5 Professional
 
#3

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 15:53
Wenn Du nur die Integer-Potenzen von 10 benötigtst, könntest Du so vorgehen:
Delphi-Quellcode:
Function IntPower_of_10(n: Word): Extended;
// Integerpotenzen von 10
VAR
  i, Pow: Integer;
Begin
  Pow:= 1;

  For i:= 1 To n Do
  Begin
    Pow:= Pow*10;
  End;

  Result:= Pow;
End;{IntPower_of_10}
Gruß, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)

Geändert von Andreas13 ( 8. Apr 2021 um 16:21 Uhr)
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 16:43
Hallo Andreas13,

Danke für den Tipp mit Power().
Ich hatte ein Stück meiner alternativen Round-Funktion für das Beispiel oben übernommen.
Ich kenne das RundungsProblem mit doubles aus C++ / Visual Studio. Dafür habe ich damals eine Funktion zusammengeschrieben, welche berechnete double-Werte korrekt rundet. Und da ich auch im Delphi immer wieder mal Rundungs-Probleme mit doubles hatte, habe ich diese Funktion von C nach Delphi übersetzt und der Einfachheit halber Power(10,AnzNachkommaStellen) zum Potenzieren genutzt. Das hatte damals mein RundungsProblem gelöst.

Wie ich aber gelesen habe, sollen die größeren Datentypen wie real oder extended nicht mehr diese RundungProblem haben. Ging die letzten paar Jahre ja auch gut.
Daher fand ich es komisch, dass, wenn ich im Delphi mit der 206.5 [Netto_Org] weiter rechne, dann doch wieder dieser Rundungsfehler wieder auftritt.
Ist mit AsCurrency gelöst.
Komisch finde ich es immernoch, weshalb AsCurrency funktioniert und AsFloat nicht. Naja ...

Das der Datentyp Currency auf "nur" max. 4 Nachkommastellen exakt ist, ist mir im Rechnungswesen ausreichend.
Hatte mich nur gewundert, weshalb der SQL-Server hier falsch rundet. Aber das wird wohl dem DB-Datentyp float geschuldet sein.
Hätte der Entwickler (ist nicht mein Projekt) hier Money benutzt, wäre das Problem evtl. gar nicht aufgetreten.

Das der Debugger auch nur gerundete Werte anzeigt, is natürlich ne fiese Falle. Kenne ich aus Visual Studio anders.

Und ja, [Netto_Org] ist genau 206,50. Zumindest so weit ich das in der DB sehen und zusammen rechnen kann. Steht auch so auf dem Papier.
Auch kenne ich weitestgehend den Code der Anwendung (nicht mein Projekt), die die Rechnungen erstellt. Hier werden explizit nur 2-stellige Beträge in die DB geschrieben, eben um spätere Rundungsfehler zu vermeinden.
Scheint dann ja wohl doch nicht zu funktionieren^^ Nicht mein Projekt!
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
724 Beiträge
 
Delphi XE5 Professional
 
#5

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 17:08
Bei allen RealTypen gibt es unvermeidbare Rundungsfehler. Das liegt in der Natur der Sache, denn es gibt unendlich viele Reelle Zahlen, die wir mittels Single, Real48, Double oder Extended auf eine endliche Menge binärer Darstellungen mit endlichen Ziffern abbilden.
Selbst die Dezimalzahl 0,1 läßt sich binär nicht exakt darstellen, wodurch bereits bei der Eingabe ein Rundungsfehler entsteht. Da hilft es auch nicht, wenn man die Dateneingabe auf 2 Nachkommastellen begrenzt.
Zitat:
Ging die letzten paar Jahre ja auch gut.
Ja, Du hast eben Glück gehabt, oder der Fehler ist niemandem aufgefallen.

Rundungsfehler sind ein ewiges Problem der Real-Zahl-Arithmetik. Und es gibt wegen der obigen Problematik „unendlich gegen endlich“ keine Lösung dafür. Es hilft nur, wenn man mit wesentlich meeeeeeehr Ziffern rechnet, also Extended oder noch mehr, und erst ganz am Ende der Berechnung rundet. Für meine kritischen Berechnungen verwende ich Multipräzisions-Arithmetik-Routinen mit 200 … 500 Stellen und konvertiere das Ergebnis auf Extended. Und trotzdem muß ich zahlreiche Vorkehrungen treffen, wenn z. B. eine eigentlich positive kleine Zahl infolge von Rundungsfehlern plötzlich negativ wird und die darauffolgende Operation (Quadratwurzel, Logarithmus etc.) versagen würde. Rundungsfehler haben mich bisher manch ein graues Haar und schlaflose Nächte gekostet.
Gruß, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
724 Beiträge
 
Delphi XE5 Professional
 
#6

AW: Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 17:40
Noch eine kleine Ergänzung, falls es jemanden interessieren sollte. Neben der Verwendung von vieeeeeelen Nachkommastellen (Multipräzisions-Arithmetik) gibt es etliche Literaturquellen mit ausgefeilten Algorithmen zur Fehlerkompensation diverser Rechenoperationen innerhalb der endlich begrenzten Stellenzahl (meistens für den DatenType Double).

Gute Beschreibungen sind zu finden u. a. in folgenden exzellenten Büchern:

1): Knuth: The Art of computer programming, Volume 1 bis 4A (1997, 1998, 2011)
2): Higham: Accuracy an Stability of Numerical Algoritms (2002)
3): Einarsson: Accuracy and Reliability in Scientific Computing (2005)

Gruß, Andreas
[edit]
PS:
... und noch mehr gute Fachbücher:

4): Muller + Brisebarre + Dinechin + Jeannerod et al: Handbook of Floating-Point Arithmetic (2010)
5): Nassif + Fayyad: Introduction To Numerical Analysis And Scientific Computing (2014)
6): Sterbenz: Floating-Point Computation (1974)
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)

Geändert von Andreas13 ( 8. Apr 2021 um 19:00 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:19 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