Hallo!
Ich habe eine Art "Kalkulations-Tabelle", die in verschiedenen Währungen angezeigt werden muss. In die Tabelle werden Stückpreise eingegeben, Gesamtpreise und Summe wird daraus errechnet. Hierbei treten Rundungs-Probleme auf. Das heißt, wenn ich eine Zahl mit einer Währungkurs mit 5 Nachkommastellen multipliziere, bekomme ich eine Zahl mit mehr Nachkommastellen, und irgendwie bin ich nicht ganz sicher wie ich damit umgehen muss. Ich habe mal gehört dass es bestimmte Regeln für die Umrechnung von DEM -> EUR gab (habe ich allerdings noch nicht gefunden), gibt es sowas auch für allgemeine Währungsumrechnungen? Also so Vorgaben wie "hier wird gerundet, hier wird mit der gerundeten Zahl gerechnet...".
Damit man sich das besser vorstellen kann, hier mal eine beispielhafte Tabelle:
Artikel | Stückpreis | Anzahl | Gesamtpreis
---------------+--------------+------------+--------------
Bleistift | 0,55000 | 150 | 83,50000
Briefumschlag | 0,21000 | 1200 | 252,00000
Kugelschreiber | 1,29000 | 180 | 232,20000
----------------------------------------------------------
Summe 566,70000
Bis hier noch sehr einfach. Die Preise und auch der Faktor (z.B. Währung) sollen 5-stellig sein. Ich muss leider etwas krummere Zahlen verwenden, weil das Problem sonst nicht deutlich wird. Angenommen das hat jetzt jemand in der Währung XYZ mit dem Umrechnungskurs 1,26537(zum EUR) eingegeben. Jetzt möchte ich mir diese Tabelle aber in EUR anzeigen, also die Preise durch den Faktor teilen:
Artikel | Stückpreis | Anzahl | Gesamtpreis
---------------+--------------+------------+--------------
Bleistift | 0,43466 | 150 | 65,19900
Briefumschlag | 0,16596 | 1200 | 199,15200
Kugelschreiber | 1,01946 | 180 | 183,50280
----------------------------------------------------------
Summe 447,85380
In diesem Fall habe ich die Stückpreise durch den Faktor(Währungskurs = 1,26537) dividiert, auf 5 Stellen gerundet, und damit weiter gerechnet. Das alles entscheidende ist die Summe, denn die wird später überwiesen, und sollte also stimmen. Aufgrund der Rundung kommt man bei der manuelle Berechnung der Summe aber auf einen anderen Wert:
566,70000 / 1,26537 = 447,85320 != 447,85380
Gut das ist jetzt nicht viel, mit anderen Zahlen hatte ich hier aber auch schon eine Differenz von 150 EUR.
Was kann ich dagegen machen? Ich könnte intern/transparent mit mehr Nachkommastellen rechnen, das reduziert das Problem, beseitigt es allerdings nicht (schon nach 1-2 Berechnungen entstehen meist zu viele Nachkommastellen...). Ganz im Gegenteil kann dies auch zu neuen Problemen führen, wenn mit anderen Zahlen als angezeigt tatsächlich gerechnet wird.
Gut, da die Summe der entscheidende Preis ist (der wird schließlich vom Konto abgebucht), könnte man ja auf die Idee kommen, diesen, bzw. die Gesamtpreise zu speichern, und die Einzelpreise aus den Gesamtpreisen zu errechnen. Heißt also, ich rechne die letzte Spalte um und speichere das, und später errechne ich daraus anhand der Mengen auch die Stückpreise. Mal am Beispiel:
Artikel | Stückpreis | Anzahl | Gesamtpreis
---------------+--------------+------------+--------------
Bleistift | 0,43466 | 150 | 65,19832 (= 83,50000 / 1,26537)
Briefumschlag | 0,16596 | 1200 | 199,15124 (")
Kugelschreiber | 1,01946 | 180 | 183,50364 (")
---------------+--------------+------------+--------------
Summe 447,85320
Soweit so gut. Nur leider, wenn jetzt jemand mit dem Taschenrechner nachrechnet:
0,43466 * 150 = 65,19900 != 65,19832 => BETRUG!
Auch der Stückpreis direkt umgerechnet stimmt nicht:
0,43466 * 1,26537 = 0,55001 != 0,55000
wobei letzters vorerst nicht ganz so schlimm ist, die Summe ist wichtig. Trotzdem darf es keine offensichtlichen "Rechenfehler" wie oben geben.
Und es gibt ein weiteres Problem. Der EUR ist die Referenz-Währung, das heißt dieser Preis zählt später, entsprechend wird auch alles in EUR gespeichert. Das heißt, ich speichere nicht den vom Anwender eingegebenen Preis, sondern einen gerundeten EUR-Preis, und rechne ihm dann bei der Anzeige seine Preise entsprechend mit seinem Währungskurs um. Durch die Rundung hier kann es passieren, dass er auf einmal einen anderen Preis da stehen hat, den er gar nicht eingegeben hatte. Genau das passiert auch in diesem Fall. Egal welche der beiden Methoden zur Umrechnung ich verwende, ich speichere z.B.
0,55000 / 1,26537 = 0,43466
in der Datenbank als Stückpreis für den Bleistift, und wenn ich ihm die Tabelle erneut anzeige, dann erhalte ich bei der Berechnung
0,43466 * 1,26537 = 0,55001 != 0,55000
Das heißt er gibt "0,55" ein, es wird aber ein minimal anderer (gerundeter) Wert gespeichert. Somit kann ich nie wieder auf die Zahl kommen, die ursprünglich mal eingegeben wurde. Mit anderen Zahlen sind auch hier größere Abweichungen möglich.
Ich sehe 2 Probleme bei der Berechnung:
1. Es wird mit gerundeten Werten multipliziert/dividiert, das führt dazu, dass ein Teil der Informationen verloren geht. Dadurch die Fehler in den Berechnungen mit "Stückpreis x Menge".
2. Es wird nicht das eingegebene Gebot gespeichert, sondern ein gerundetes Ergebnis einer Division. Auch hier gehen Informationen durch die Rundung verloren, die dann für den Anwender zu nicht nachvollziehbaren Werten führen.
Wenn man zusätzliche Nachkommastellen speichert, verlagert man das Problem einfach entsprechend weiter nach hinten, aber man wird es nicht los. Bei entsprechend großen und genauen Zahlen wird es weiter Probleme geben, auch mit 10 Nachkommastellen.
Außerdem werden nur 5 Nachkommastellen angezeigt, wenn ich eine Zahl aber tatsächlich mit mehr Nachkommstellen speichere und zu Berechnungen verwende, dann ist das Ergebnis zwar richtig(er), aber da in der Anzeige gerundet wird, ist diese nicht mehr mit dem Taschenrechner nachvollziehbar.
Im Moment bin ich der Ansicht, dass sich das Problem nicht vollständig beseitigen lässt, egal wie man es dreht und wendet. Daher fällt mir bisher nur ein, die entsprechenden problematischen Umrechnungen an Stellen zu verlagern, wo es "nicht so schlimm ist". Schlimm ist es z.B., wenn ein Anwender einen Preis eingibt, und das System tatsächlich einen anderen Preis speichert. Daher sollte man wohl eher die originale Eingabe speichern, und von dort aus umrechnen. Dann hat derjenige der was eingibt eine konsistente Tabelle. Außerdem kann man dann von diesen Werten ausgehend, also von einem ungerundeten/originalen Preis andere Preise berechnen, auch in anderen Kursen.
Aber leider habe ich dann immer nur eine konsistente/schlüssige Tabelle. Wenn ich will das alle Tabellen in sich logisch/nachrechenbar sind, habe ich das Problem dass ich nicht überall auf dieselbe Summe komme.
Entweder ich rechne von dem angezeigten (gerundeten) Stückpreis den Gesamtpreis aus, habe so eine Konsistente Tabelle, oder ich Rechne von dem angezeigten Gesamtpreis den Stückpreis aus, was dazu führt dass zwar überall Gesamtpreise und Summen stimmen, aber nicht alle Tabellen in sich schlüssig sind. Irgendwie beides keine angenehmen Alternativen.
Ist etwas kompliziert wie ich finde ;-)
Muss man mit diesen Unstimmigkeiten leben, oder gibt es eine Möglichkeit dass alle Werte stimmen? Oder gibt es irgendwo Normen/Vorschriften/Standards wie man solche Umrechnungen zu machen hat? Oder hat jemand Ideen für einen ganz anderen Ansatz? Im Moment beißt sich die Katze in den Schwanz...
Viele Grüße
Andreas