Rundungsfehler

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 13072
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Rundungsfehler

Beitrag von Jan » Di, 27. Mär 2018 13:13

Ich hatte gerade eine interessante Diskussion mit einem Kunden. Und brauch da mal Eure Sachkenntnis.

Wir leben ja ständig mit dem Problem der CPU-Rundungsfehler.Die zwar erst irgendwo in der 4. oder 6. Stelle auftreten, aber doch irgendwo relevant werden können.

Wie verhält sich das aber exakt? Kann ein 1,87 € nur irgendwo zwischen 1,87 € und 1,870001 € liegen? Oder auch 1,8699999 € sein? Soll sagen: Rundungsfehler nur nach oben? Oder auch runter?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14546
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Rundungsfehler

Beitrag von brandelh » Di, 27. Mär 2018 13:15

in beide Richtungen, wobei ich denke, dass es wahrscheinlicher nach unten geht
Gruß
Hubert

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14546
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Rundungsfehler

Beitrag von brandelh » Di, 27. Mär 2018 13:22

Ich habe einmal ein Programm geschrieben, das für viele Monate Leistungen nachberechnet hat, da war auch Verzinsung nötig.
Beim reinen addieren ist das meist kein Problem, aber je Monat wurden die 4 % Zinsen berechnet und gedruckt.
Die Summe im berechneten Summen-Feld und die manuelle Summe über die Zeilen, konnten einige Euro ausmachen.

Daher habe ich dann in jeder Zeile den Zinsbetrag auch intern gerundet, bevor ich den addiert habe, danach war es gut.

Aber um auch bei großen Beträgen wirklich sicher zu sein, müsste man einen speziellen Datentyp haben.
Unser Wirtschafts-Basic in der Schule konnte mit richtigen Dezimalzahlen rechnen (die haben das irgendwie nachgebildet) ...
Andere Systeme nutzen 64 Bit Ganzzahlen und rechnen in Bruchteilen von Cent ...

25,55 => intern dann als 64 bit Integer => 255500 Cent/10000
Gruß
Hubert

DelUser01

Re: Rundungsfehler

Beitrag von DelUser01 » Di, 27. Mär 2018 14:14

Hallo Jan

habe auch seit Jahren manchmal noch so ein Rundungsproblem und noch nicht herausgefunden woran es liegt.

Z.B.
Es wird berechnet (zusammengezählt) was heute bezahlt (überwiesen) werden muss.
Der User bekommt eine Zahl in einem SLE angezeigt - z.B. 25.000,00 Euro
und wird gefragt wieviel er bezahlen will. Er bestätigt den Betrag 25.000,00 mit Return.
Dann kommt es manchmal vor, dass das eine Rechnung weglässt weil 1 Cent zu wenig bestätigt wurde.
Also war die angezeigte Zahl nicht 25.000,00 sondern z.B. 25.000,000001 oder so.
Der Kunde hat sich dran gewöhnt und gibt meist automatisch schon 1 Cent mehr ein.
Warum auch immer... ist doch doof.

In meinem Errorlog sind solche Zahlen häufiger zu sehen
wenn ich eine Zahl ausgebe mit
? "Code: " , nCode
Da steht dann im Log z.B:
Code: 15,9999999... usw. , nZahl ist aber 16.
Gebe ich die Zahl aus mit ? Var2Char( nCode ) wird wieder 16 angezeigt.
Für die Wandlung von nCode in einen String habe ich auch eine Funktion welche bei derselben Zahl auch keine Rundungsprobleme macht. Die Funktion schaut wie viele Kommastellen der Wert hat und schneidet diese dann ab. Wenn die Zahl im Speicher 16,000000000 hat steht im String "16" und nicht die 15,999999

Das ist immer wieder seltsam...

Benutzeravatar
DennisK
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 33
Registriert: Sa, 17. Mär 2018 9:26
Wohnort: Neuenkirchen

Re: Rundungsfehler

Beitrag von DennisK » Do, 29. Mär 2018 17:21

Das alte Problem mit den Gleitkommazahlen. Irgendwann wird halt abgeschnitten.

10/3 = 3,33333333333333333333
3,33333333333333333333*3 = 9,99999999999999999999

Das ist halt Annähern und kein genaues Rechnen.
Ist es zu Ende denkbar? Widerspricht es nicht den Naturgesetzen? Dann ist es machbar!

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 87
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: Rundungsfehler

Beitrag von Statler » Di, 03. Apr 2018 11:35

Hallo zusammen,

Binaer kann nicht immer verlustfrei nach Dezimal gewandelt werden und umgekehrt. Da liegt das grundsaetzliche Problem

nZahl:= ROUND (nZahl + 0.0001, 2)

So bearbeite ich meien Euro Werte, wenn es Probleme geben koennte

Gruss

Achim

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7284
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Rundungsfehler

Beitrag von Tom » Di, 03. Apr 2018 11:40

Binaer kann nicht immer verlustfrei nach Dezimal gewandelt werden und umgekehrt.
Bitte was? :shock: Binäre und dezimale Zahlendarstellungen machen exakt das gleiche, nur zu einer anderen Basis. Selbstverständlich geht das immer und immer in beide Richtungen völlig verlustfrei.
Herzlich,
Tom

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 87
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: Test Mapi

Beitrag von Statler » Di, 03. Apr 2018 13:35

Hallo,

ich rede von gebrochenen Zahlen!

ich kann mich noch schwach an eine Vorlesung ueber verschiedene Formen der Zahlendarstellungen erinnern, da wurde aud das Problem bei Real-Zahlen explizit hingewiesen. Daher darf man eine Real-Zahl auch nie auf 0 Pruefen, sondern auf < 0,....1.

https://www.sps-lehrgang.de/umrechnung- ... malzahlen/

Ich bin bereits mehrfach auf das Problem gestossen, das bei der Addition/Subtraktion von Euro-Werten aus der Datenbank, also definitiv nur 2 Stellen, hin und wieder irgendwas auf der x-ten Stelle erscheint. Sowas kann eigentlich nicht sein ...

Wenn man dann versucht, auf 0 zu pruefen (Konto ist ausgeglichen) gibt es hin und wieder, jedoch streng reproduzierbar, Probleme.

Gruss

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14546
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Rundungsfehler

Beitrag von brandelh » Di, 03. Apr 2018 14:02

Ähem ... TOM, nicht mit den verwendeten 8 Bit Fließkomma Zahlen, wenn die Genauigkeit höher geht, gibt es da immer Verluste.
Gruß
Hubert

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14546
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Rundungsfehler

Beitrag von brandelh » Di, 03. Apr 2018 14:30

Aus dem Grunde vergleiche ich gerne mit Str(nWert1,18) == Str(nWert2,18)
Wenn man es sicher machen will, muss man noch die ********* beim Zahlenüberlauf abfangen ;-)
Gruß
Hubert

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7284
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Rundungsfehler

Beitrag von Tom » Di, 03. Apr 2018 15:13

Ihr redet von reellen und natürlichen Zahlen. Und selbst bei denen gilt: Eine Zahl, die sich dezimal (zur Basis 10) repräsentieren lässt, lässt sich verlustfrei auch binär (zur Basis 2) repräsentieren. Zumindest theoretisch. Denn 1/3 zum Beispiel lässt sich als einzelne Zahl überhaupt nicht repräsentieren, jedenfalls nicht vollständig.
Herzlich,
Tom

DelUser01

Re: Rundungsfehler

Beitrag von DelUser01 » Di, 03. Apr 2018 15:35

Das ist doch genau der Effekt von dem ich weiter oben schon geschrieben habe.

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 87
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: Rundungsfehler

Beitrag von Statler » Di, 03. Apr 2018 20:41

Hallo Tom.

n:= 0.876 / 3 * 3
debugout (STR (n, 24, 16))

da sollte eigenlich 0.876 rauskommen, aber 0.8759999999... erscheint.

Wie gesagt,
https://www.sps-lehrgang.de/umrechnung- ... malzahlen/
das Beispiel ganz unten macht die Sache klar.

Gruss

UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2532
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Kontaktdaten:

Re: Rundungsfehler

Beitrag von UliTs » Mi, 11. Apr 2018 12:17

Tom hat geschrieben:
Di, 03. Apr 2018 15:13
Ihr redet von reellen und natürlichen Zahlen. Und selbst bei denen gilt: Eine Zahl, die sich dezimal (zur Basis 10) repräsentieren lässt, lässt sich verlustfrei auch binär (zur Basis 2) repräsentieren. Zumindest theoretisch. Denn 1/3 zum Beispiel lässt sich als einzelne Zahl überhaupt nicht repräsentieren, jedenfalls nicht vollständig.
Z.B. 0,1 oder 0,9 lassen sich nicht im Binärsystem darstellen. Deshalb ist bei Binärsystem oft 0,1 + 0,9 <> 1,0 :-)
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7284
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Rundungsfehler

Beitrag von Tom » Mi, 11. Apr 2018 12:57

Ui, Uli.

Den Rechenvorgang, bei dem 0,1 + 0,9 nicht 1,0 ergibt, musst Du mir mal zeigen. Das schaffst Du nicht einmal auf einem 4-Bit-Robotron-Rechner von 1979.

Binär repräsentierte Gleitkommazahlen nach IEEE 754 (Bits für Vorzeichen, Exponenten und Mantissen) sind sehr wohl äußerst präzise und stimmen meistens mit ihrer Dezimalrepräsentation für viele Nachkommastellen überein. Es gibt möglicherweise Artefakte bei bestimmten Bruchzahlen. Aber wenn es bei solchen Berechnungen wie der von Dir erwähnten tatsächlich Probleme gäbe, wäre es besser, die Rechner komplett wegzuschmeißen.
Herzlich,
Tom

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14546
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Rundungsfehler

Beitrag von brandelh » Mi, 11. Apr 2018 13:28

bevor Ihr euch kloppt ...

:arrow: https://de.wikipedia.org/wiki/IEEE_754
Hilfe zu 2.00 hat geschrieben:Numeric values are handled within Xbase++ in the IEEE 64 bit format for floating point numbers.
This provides a range for calculations of 10 to the power of -307 to 10 to a power of +308.
The binary representation of a floating point number yields a 16 decimal digit precision.

The display of numeric values on the screen is predictable only up to 16 places before the decimal and 15 places after the decimal.
Numeric values are displayed with a maximum of 31 digits.
If there are more pre or post decimal numerals, asterisks * or nulls 0 are shown in the display of the number.
Richtig ist, dass mit diesen Werten schon sehr große Zahlen benötigt werden um eine Differenz zu erzeugen und dass immer wenn Perioden im Spiel sind,
weder mit dem einen noch mit dem anderen eine Exakte Angabe möglich ist. Daher kürzt man ja solche Berechnungen auch gerne.

Man muss immer Aufpassen, ob bei seinen Zahlenbereichen Rundungsfehler eine Rolle spielen könnten, Vergleiche auf = würde ich daher immer mit STR(nWert) oder Round() durchführen,
wobei die "*" beim Überlauf berücksichtigt werden müssen.

Ich denke, dass vieles von dem was wir an Fehlern erwartet hätten auf DOS Clipper zurück geht,
haben wir dort schon so große Zahlen gehabt oder waren es da nur 8 Stellen nach dem Komma oder 15 insgesamt ... ich weiß es nicht mehr.
Ich meine aber Clipper hatte mit 32 Bit Single Floating Point deutlich weniger Genauigkeit.

Zum Test habe ich mal diese Formeln eingegeben und Berechnen lassen:

Code: Alles auswählen

Berechnungen:
0.1 + 0.9               =>           1.0
0.1 + 0.9 = 1.0         =>           J
1   - 0.1 - 0.9         =>           0.0
1   - 0.1 - 0.9 = 0     =>           J
1.0 - 0.1 - 0.9 = 0     =>           J

Ende
Gruß
Hubert

UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2532
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Kontaktdaten:

Re: Rundungsfehler

Beitrag von UliTs » Mi, 11. Apr 2018 14:10

Tom hat geschrieben:
Mi, 11. Apr 2018 12:57
Ui, Uli.

Den Rechenvorgang, bei dem 0,1 + 0,9 nicht 1,0 ergibt, musst Du mir mal zeigen. Das schaffst Du nicht einmal auf einem 4-Bit-Robotron-Rechner von 1979.

Binär repräsentierte Gleitkommazahlen nach IEEE 754 (Bits für Vorzeichen, Exponenten und Mantissen) sind sehr wohl äußerst präzise und stimmen meistens mit ihrer Dezimalrepräsentation für viele Nachkommastellen überein. Es gibt möglicherweise Artefakte bei bestimmten Bruchzahlen. Aber wenn es bei solchen Berechnungen wie der von Dir erwähnten tatsächlich Probleme gäbe, wäre es besser, die Rechner komplett wegzuschmeißen.
Hallo Tom,

dann versuche doch einmal 0,1 im Binärsystem bei endlicher Stellenanzahl darzustellen -> geht nicht ;-) .
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück

Antworten