Mir ist bewusst, dass Gleitkomma-Arithmetik Präzisionsprobleme hat. Normalerweise überwinde ich sie, indem ich zu einer festen Dezimaldarstellung der Zahl wechsle oder einfach den Fehler vernachlässige.
Ich weiß jedoch nicht, was die Ursachen für diese Ungenauigkeit sind. Warum gibt es so viele Rundungsprobleme mit Gleitkommazahlen?
decimal
Typ. Ein fester Punkt ist dagegen anders. Solange Ihre Reichweite begrenzt ist, ist der Fixpunkt eine gute Antwort. Aufgrund des eingeschränkten Bereichs ist Festkomma jedoch für viele mathematische Anwendungen ungeeignet, und die Implementierung von Festkommazahlen ist in der Hardware häufig nicht gut optimiert.Antworten:
Dies liegt daran, dass einige Brüche eine sehr große (oder sogar unendliche) Anzahl von Stellen benötigen, um ohne Rundung ausgedrückt zu werden. Dies gilt sowohl für die Dezimalnotation als auch für die Binärnotation. Wenn Sie die Anzahl der für Ihre Berechnungen zu verwendenden Dezimalstellen begrenzen würden (und keine Berechnungen in Bruchnotation durchführen würden), müssten Sie sogar einen einfachen Ausdruck mit 1/3 + 1/3 runden. Statt 2/3 zu schreiben, müssten Sie 0,33333 + 0,33333 = 0,66666 schreiben, was nicht mit 2/3 identisch ist.
Im Falle eines Computers ist die Anzahl der Stellen durch die technische Natur seiner Speicher- und CPU-Register begrenzt. Die intern verwendete Binärnotation fügt einige weitere Schwierigkeiten hinzu. Computer können Zahlen normalerweise nicht in Bruchnotation ausdrücken, obwohl einige Programmiersprachen diese Fähigkeit hinzufügen, wodurch diese Probleme bis zu einem gewissen Grad vermieden werden können.
Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte
quelle
Rundungsfehler entstehen in erster Linie dadurch, dass die Unendlichkeit aller reellen Zahlen unmöglich durch den endlichen Speicher eines Computers dargestellt werden kann , geschweige denn durch eine winzige Speicherscheibe wie eine einzelne Gleitkommavariable , von der viele gespeicherte Zahlen nur Näherungswerte sind die Zahl, die sie darstellen sollen.
Da es nur eine begrenzte Anzahl von Werten gibt, die keine Näherung darstellen, und jede Operation zwischen einer Näherung und einer anderen Zahl zu einer Näherung führt, sind Rundungsfehler fast unvermeidlich .
Es ist wichtig zu erkennen, wann sie wahrscheinlich ein Problem verursachen, und Maßnahmen zu ergreifen, um die Risiken zu mindern .
Zusätzlich zu David Goldbergs grundlegendem Wissen, das jeder Informatiker über Fließkomma-Arithmetik wissen sollte (von Sun / Oracle als Anhang zu ihrem Numerical Computation Guide neu veröffentlicht ), das von Thorsten erwähnt wurde, lieferte das ACCU- Journal Overload eine hervorragende Leistung Artikelserie von Richard Harris über den Floating Point Blues .
Die Serie begann mit
Richard erklärt zunächst die Taxonomie von reellen Zahlen, rational, irrational, algebraisch und transzendental. Anschließend erklärt er die IEEE754-Darstellung, bevor er auf Abbruchfehler und Ausführungsreihenfolgeprobleme eingeht.
Wenn Sie nicht tiefer lesen, haben Sie eine hervorragende Grundlage für die Probleme, die mit Gleitkommazahlen verbunden sind.
Wenn Sie jedoch mehr wissen möchten, fährt er fort
Anschließend versucht er, Ihnen bei der Heilung Ihres Calculus Blues zu helfen
und last but not least gibt es
Die gesamte Artikelserie ist einen Blick wert und mit insgesamt 66 Seiten immer noch kleiner als die 77 Seiten des Goldberg-Papiers .
Obwohl diese Reihe fast denselben Bereich abdeckt, fand ich sie zugänglicher als Goldbergs Artikel . Ich fand es auch einfacher, die komplexeren Teile des Papiers zu verstehen, nachdem ich die früheren Artikel von Richards gelesen hatte. Nach diesen frühen Artikeln verzweigt sich Richard in viele interessante Bereiche, auf die das Goldberg-Papier keinen Einfluss hat.
Wie so spricht ak in den Kommentaren erwähnt:
quelle
Nun, Thorsten hat den endgültigen Link . Ich würde hinzufügen:
Jede Form der Darstellung weist Rundungsfehler für eine bestimmte Zahl auf. Versuchen Sie, 1/3 in IEEE-Gleitkomma oder als Dezimalzahl auszudrücken. Weder kann es genau tun. Dies geht über die Beantwortung Ihrer Frage hinaus, aber ich habe diese Faustregel erfolgreich angewendet:
quelle
Was bisher anscheinend nicht erwähnt wurde, sind die Konzepte eines instabilen Algorithmus und eines schlecht konditionierten Problems . Ich werde zuerst auf die ersteren eingehen, da dies eine häufigere Gefahr für unerfahrene Numeriker darstellt.
Betrachten Sie die Berechnung der Potenzen des (reziproken) goldenen Schnitts
φ=0.61803…
. Eine Möglichkeit ist die Verwendung der Rekursionsformelφ^n=φ^(n-2)-φ^(n-1)
, beginnend mitφ^0=1
undφ^1=φ
. Wenn Sie diese Rekursion in Ihrer bevorzugten Computerumgebung ausführen und die Ergebnisse mit genau bewerteten Leistungen vergleichen, werden Sie eine langsame Erosion signifikanter Zahlen feststellen. Folgendes passiert zum Beispiel in Mathematica :Das angebliche Ergebnis für
φ^41
hat das falsche Vorzeichen, und noch früher haben die berechneten und tatsächlichen Werte fürφ^39
keine gemeinsamen Ziffern (3.484899258054952
* ^ - 9for the computed version against the true value
7.071019424062048*^-9
). Der Algorithmus ist daher instabil, und man sollte diese Rekursionsformel nicht in ungenauer Rechnung verwenden. Dies liegt an der inhärenten Natur der Rekursionsformel: Es gibt eine "abklingende" und "wachsende" Lösung für diese Rekursion und der Versuch, die "abklingende" Lösung durch Vorwärtslösung zu berechnen, wenn es eine alternative "wachsende" Lösung gibt für numerische Trauer. Man sollte also sicherstellen, dass seine numerischen Algorithmen stabil sind.Nun zum Konzept eines schlecht konditionierten Problems: Auch wenn es einen stabilen Weg gibt, etwas numerisch zu tun, kann es durchaus sein, dass das Problem, das Sie gerade haben, von Ihrem Algorithmus nicht gelöst werden kann. Dies liegt am Problem selbst und nicht an der Lösungsmethode. Das kanonische Beispiel in der Numerik ist die Lösung linearer Gleichungen mit der sogenannten "Hilbert-Matrix":
Die Matrix ist das kanonische Beispiel für eine schlecht konditionierte Matrix: Wenn Sie versuchen, ein System mit einer großen Hilbert-Matrix zu lösen, erhalten Sie möglicherweise eine ungenaue Lösung.
Hier ist eine Mathematica- Demonstration: Vergleichen Sie die Ergebnisse der exakten Arithmetik
und ungenaue Arithmetik
(Wenn Sie es in Mathematica ausprobiert haben , werden Sie einige Fehlermeldungen bemerken, die auf eine schlechte Konditionierung hinweisen.)
In beiden Fällen ist es keine Heilung, einfach die Präzision zu erhöhen. es wird nur die unvermeidliche Erosion von Zahlen verzögern.
Dies ist, was Sie konfrontiert werden könnten. Die Lösungen könnten schwierig sein: Zum einen gehen Sie entweder zurück zum Zeichenbrett oder stöbern in Zeitschriften / Büchern / was auch immer, um herauszufinden, ob jemand anderes eine bessere Lösung gefunden hat als Sie; Zum anderen geben Sie das Problem entweder auf oder formulieren es neu, sodass es leichter zu lösen ist.
Ich werde Sie mit einem Zitat von Dianne O'Leary verlassen:
quelle
da Dezimalzahlen zur Basis 10 nicht in Basis 2 ausgedrückt werden können
oder mit anderen Worten, 1/10 kann nicht in einen Bruch mit einer Potenz von 2 im Nenner umgewandelt werden (was im Wesentlichen Gleitkommazahlen sind).
quelle
9*3.3333333
in Dezimalzahlen und vergleichen Sie es mit9*3 1/3
.1 + .1 != .2
da binäre Gleitkommacodierung verwendet wird, nicht dezimal.1.0/3.0*3.0 != 1.0
da Gleitkomma-Binärcodierung verwendet wird, nicht Trinary.In der Mathematik gibt es unendlich viele rationale Zahlen. Eine 32-Bit-Variable kann nur 2 32 verschiedene Werte und eine 64-Bit-Variable nur 2 64 Werte haben. Daher gibt es unendlich viele rationale Zahlen, die keine genaue Darstellung haben.
Wir könnten Schemata entwickeln, mit denen wir 1/3 oder 1/100 perfekt darstellen können. Es stellt sich heraus, dass dies für viele praktische Zwecke nicht sehr nützlich ist. Es gibt eine große Ausnahme: In der Finanzwelt tauchen häufig Dezimalbrüche auf. Das liegt hauptsächlich daran, dass Finanzen im Wesentlichen eine menschliche und keine physische Tätigkeit sind.
Aus diesem Grund verwenden wir normalerweise binäre Gleitkommazahlen und runden jeden Wert, der nicht binär dargestellt werden kann. Im Finanzbereich wählen wir manchmal dezimale Gleitkommazahlen und runden die Werte auf den nächsten Dezimalwert.
quelle
"√2"
. (Mein alter HP-48-Rechner konnte genau das, und das Quadrieren dieses Wertes ergab genau das2.0
.) Es gibt nur eine zählbare Unendlichkeit darstellbarer reeller Zahlen für eine endliche Darstellung - aber keine Berechnung kann eine Zahl ergeben, die nicht ist. grundsätzlich darstellbar. In der Praxis wird die Menge der darstellbaren Zahlen durch binäre Gleitkommazahlen drastisch begrenzt, was sich in einer rasanten Geschwindigkeit und einem geringen Speicherplatz im Vergleich zu symbolischen Darstellungen niederschlägt.Das einzige wirklich offensichtliche "Rundungsproblem" bei Gleitkommazahlen, über das ich nachdenke, sind Filter mit gleitendem Durchschnitt:
$$ \ begin {align} y [n] & = \ frac {1} {N} \ sum \ limits_ {i = 0} ^ {N-1} x [ni] \ & = y [n-1] + \ frac {1} {N} (x [n] - x [nN]) \ \ end {align} $$
Damit dies ohne die Entstehung von Rauschen funktioniert, müssen Sie sicherstellen, dass das in den aktuellen Samples hinzugefügte $ x [n] $ genau mit dem Wert von $ x [nN] $ übereinstimmt, den Sie in das subtrahieren Zukunft. Wenn dies nicht der Fall ist, ist etwas anderes, als wenn ein kleiner Trottel in Ihrer Verzögerungsleitung stecken bleibt und niemals herauskommt. Das liegt daran, dass dieser Filter mit gleitendem Durchschnitt tatsächlich mit einem IIR aufgebaut ist, der einen geringfügig stabilen Pol bei $ z = 1 $ und eine Null aufweist, die ihn im Inneren aufhebt. Aber es ist ein Integrator und jeder Mist, der integriert und nicht vollständig entfernt wird, wird für immer in der Integratorsumme vorhanden sein. Dies ist der Punkt, an dem Festkommazahlen nicht dasselbe Problem haben wie Gleitkommazahlen.
quelle