Steffen Gerlach: Fließkommafehler

Beitrag lesen

Hi,

Michal hat Deine Frage im Wesentlichen beantwortet. Stell Dir doch mal die Frage, warum Du den Bereich ausgerechnet in 0.2er Schritten durchgehst. Ganz einfach: weil Du gewohnt bist, im Dezimalsystem zu rechnen und 0.2er Schritte dort schöne runde Zahlen ergeben. Du würdest nie auf die Idee kommen, etwa 1/7-Schritte zu verwenden, weil schon der erste Schritt mit einer Dezimalzahl nicht exakt dargestellt werden kann, und nach sieben Mal Addieren eben nicht exakt 1.0 herauskommt - egal, mit wieviel Stellen Genauigkeit man rechnet. Genau das gleiche Problem hat der Computer, wenn er mit 0.2 rechnen soll. Was Du ihm als "extreme Fehler" ankreidest, sind zwangsläufige Abweichungen in der letzten Kommastelle. Der Computer kann z.B. den Wert 2.6 nicht exakt berechnen, weil es für diesen Wert gar keine Darstellung im Binärsystem gibt. Das Gleiche gilt auch für 2.8, nur sind nach der ersten Rechnung die Abweichungen noch so gering, dass sie weggerundet werden.

Der Trick mit dem *100 und späteren /100 kann in sofern funktionieren, als dabei die meiste Zeit mit ganzen Zahlen (also exakt!) gerechnet wird und nur ganz zuletzt eine einzelne unexakte Operation folgt. Du hast den Trick allerdings falsch angewendet, da bei Dir doch wieder in jedem Schritt eine unexakte Operation erfolgt (/100), die in alle folgenden Schritte einfließt. Du müsstest vollständig in ganzen Zahlen rechnen und erst das Ergebnis unmittelbar vor der Ausgabe durch 100 (oder was auch immer) teilen.

Es gibt m.E. nur zwei wirklich saubere Lösungen für das Problem:

(1) Du lässt dem Rechner die Hoheit über seine Zahlen, musst dann aber die standardmäßige Umwandlung Zahl->String algorithmisch nachbearbeiten, da diese von einer zu hohen Genauigkeit ausgeht. Ein Wert wie z.B. "-1.2000000000000006" müsste dann über String-Funktionen (nicht numerisch!) auf "-1.2" gebracht werden.

(2) Du rechnest von vornherein nur mit Zahlen, die im Binärsystem exakt darstellbar sind. Statt 0.2er Schritten könntest Du z.B. 0.25er oder 0.203125er (=13/64) Schritte wählen.

Ach ja: Ich kann kein Java, das sind alles allgemeine Aussagen, die aber auch für Java zutreffen müssten.

Gruß
Steffen