Warum ist 24.0000 nicht gleich 24.0000 in MATLAB?
Schreibe ich ein Programm, wo ich brauche, um doppelte Punkte gespeichert, die in einer matrix. Das problem ist, dass, wenn es darum geht zu überprüfen, ob diese Punkte werden in der matrix mit MATLAB kann nicht erkennen, Sie in die matrix, obwohl Sie existieren.
In den folgenden code intersections
Funktion bekommt die Schnittpunkte:
[points(:,1), points(:,2)] = intersections(...
obj.modifiedVGVertices(1,:), obj.modifiedVGVertices(2,:), ...
[vertex1(1) vertex2(1)], [vertex1(2) vertex2(2)]);
Das Ergebnis:
>> points
points =
12.0000 15.0000
33.0000 24.0000
33.0000 24.0000
>> vertex1
vertex1 =
12
15
>> vertex2
vertex2 =
33
24
Zwei Punkte (vertex1
und vertex2
) sollten beseitigt werden, aus dem Ergebnis. Es sollte getan werden, durch die folgenden Befehle:
points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :);
points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);
Danach, haben wir dieses unerwartete Ergebnis:
>> points
points =
33.0000 24.0000
Das Ergebnis sollte eine leere matrix. Wie Sie sehen können, die erste (oder zweite?) paar [33.0000 24.0000]
wurde beseitigt, aber nicht die zweite.
Dann überprüfte ich diese zwei Ausdrücke:
>> points(1) ~= vertex2(1)
ans =
0
>> points(2) ~= vertex2(2)
ans =
1 % <-- It means 24.0000 is not equal to 24.0000?
Was ist das problem?
Mehr überraschend, ich habe ein neues Skript, das nur diese Befehle:
points = [12.0000 15.0000
33.0000 24.0000
33.0000 24.0000];
vertex1 = [12 ; 15];
vertex2 = [33 ; 24];
points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :);
points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);
Das Ergebnis wie erwartet:
>> points
points =
Empty matrix: 0-by-2
Sorry, habe ich nicht darauf aus, die Gefahren von floating-point-Vergleich, wenn Sie gefragt werden, über den Vergleich von Werten in deiner anderen Frage. Es hat nicht sofort auftreten, mir Sie vielleicht laufen, dass problem.
Als seitliche Anmerkung, vergleichen
1.2 - 0.2 - 1 == 0
und 1.2 - 1 - 0.2 == 0
. Überraschend, nicht wahr? Wenn Sie den Umgang mit floating-point-zahlen, die Reihenfolge der Operationen ankommt.Tock: Wie der Autor die Frage, konnte ich gar nicht verstehen, den Titel, den du gewählt für meine Frage. Auch ist es nicht die Tatsache widerspiegeln, dass MATLAB nicht das gesamte floating-point-Teil der Nummer, wenn Sie drucken Sie die variable.
Ich sehe. aber in der Regel setzen Sie die "duplizieren" - label auf die neuere Frage. Bitte Lesen Sie die Regeln für die doppelte Beschriftung: meta.stackexchange.com/questions/10841/...
InformationsquelleAutor Kamran Bigdely | 2009-03-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem betrifft, wie floating-point-zahlen vertreten sind, auf einem computer. Eine ausführlichere Diskussion von Fließkomma-Darstellungen erscheint gegen Ende meiner Antwort ("Gleitkommadarstellung"). Die TL;DR version: da Computer mit begrenzten Mengen an Speicher, die zahlen können nur dargestellt werden mit endlicher Genauigkeit. Damit wird die Genauigkeit der floating-point-zahlen ist beschränkt auf eine bestimmte Anzahl von Dezimalstellen (über 16 signifikanten Ziffern für double-precision-Werte, den Standard in MATLAB).
Tatsächliche vs. angezeigt Präzision
Nun zu den speziellen Beispiel in der Frage... während
24.0000
und24.0000
sind angezeigt in der gleichen Weise, es stellt sich heraus, dass Sie tatsächlich unterscheiden sich durch sehr kleine dezimal-Mengen in diesem Fall. Sie sehen es nicht, weil MATLAB zeigt nur 4 signifikanten Ziffern standardmäßig, halten das gesamte display sauber und ordentlich. Wenn Sie möchten, um zu sehen, die volle Genauigkeit, sollten Sie entweder die Ausgabe derformat long
Befehls oder anzeigen eines hexadezimale Darstellung der Nummer:Initialisiert Werte vs. berechnete Werte
Da es nur eine endliche Anzahl von Werten dargestellt werden kann, die für ein floating-point-Zahl, ist es möglich, für eine Berechnung zu einem Wert führen, der fällt, zwischen zwei dieser Darstellungen. In einem solchen Fall, das Ergebnis muss abgerundet werden, um einer von Ihnen. Dies stellt eine kleine machine-precision-Fehler. Dies bedeutet auch, dass die Initialisierung ein Wert, der direkt oder durch eine Berechnung geben können leicht unterschiedliche Ergebnisse. Zum Beispiel, der Wert
0.1
keine genaue floating-point-Darstellung (d.h. er bekommt leicht abgerundet), und so werden Sie am Ende mit counter-intuitive Ergebnisse zu erzielen, wie dies aufgrund der Art Rundungsfehler akkumulieren:, Wie man richtig behandeln-floating-point-Vergleiche
Da die floating-point-Werte können sich durch sehr kleine Beträge, keine Vergleiche durchgeführt werden sollte durch die überprüfung, dass die Werte innerhalb einer bestimmten Bandbreite (d.h. Toleranz) von einander, im Gegensatz zu genau einander gleich. Zum Beispiel:
anzeigen "Gleich!".
Dann könnten Sie den code ändern, um so etwas wie:
Floating-point-Darstellung
Einen guten überblick über floating-point-zahlen (und insbesondere die IEEE-754-standard für Gleitkomma-Arithmetik) ist das, Was Jeder Computer Scientist should Know About Floating-Point Arithmetic von David Goldberg.
Einen binary floating-point-Zahl ist eigentlich, dargestellt durch drei ganze zahlen: Vorzeichen-bit
s
, einer Mantisse (oder Koeffizienten/Fraktion)b
, und ein exponente
. Für double-precision-floating-point-format, jede Zahl wird repräsentiert durch 64 bits im Speicher angeordnet wie folgt:Den realen Wert kann man dann mit der folgenden Formel:
In diesem format können für die Anzahl Vertretungen in den Bereich von 10^-308 bis 10^308. Für MATLAB Sie können diese Grenzen aus
realmin
undrealmax
:Da gibt es eine endliche Anzahl von bits zur Darstellung einer floating-point-Zahl, es gibt nur so viele endliche zahlen dargestellt werden kann, die innerhalb des oben angegebenen Bereichs liegt. Berechnungen werden oft zu einem Wert führen, der nicht exakt eine dieser endlichen Darstellungen, so müssen die Werte abgerundet werden. Diese machine-precision-Fehler machen sich offensichtlich in unterschiedlicher Weise, wie bereits in den obigen Beispielen.
Um besser zu verstehen, diese Rundungsfehler ist es nützlich, zu betrachten, die relative Fließkomma-Genauigkeit, die durch die Funktion
eps
, die Quantifizierung der Abstand aus einer bestimmten Anzahl der nächsten größten floating-point-Darstellung:Beachten Sie, dass die Präzision ist relative, um die Größe einer bestimmten Anzahl vertreten; je größer die zahlen werden auch größere Entfernungen zwischen floating-point-Darstellungen, und damit weniger Ziffern für die Genauigkeit nach dem Komma. Dies kann ein wichtiger Gesichtspunkt bei einigen Berechnungen. Betrachten Sie das folgende Beispiel:
Beachten Sie, dass, wenn wir eine Verschiebung der Werte von
x
aus dem Bereich[0 1]
auf den Bereich[10000 10001]
, berechnen einen Mittelwert, dann subtrahieren Sie die mittlere offset-zum Vergleich, wir bekommen einen Wert, der unterscheidet sich für die letzten 3 signifikante Ziffern. Dies veranschaulicht, wie eine Aufrechnung oder die Skalierung der Daten ändern kann die Genauigkeit der Berechnungen durchgeführt, die ist etwas, die berücksichtigt werden, die für bestimmte Probleme.Sie können es sehen, wenn man die variable in der matrix-Ansicht. Rechtsklick auf die variable -> "Ansicht" oder sowas? Ich habe keine MATLAB hier, also kann ich nicht überprüfen.
Sie können auch sehen, kleine Unterschiede durch die Eingabe von "format " long" an der Eingabeaufforderung.
Sie haben Recht: format long Punkte = 12.000000000000000 15.000000000000000 33.000000000000000 23.999999999999996 33.000000000000000 24.000000000000000
"hex-format" kann manchmal sogar helfen, mehr als format lange hier.
InformationsquelleAutor gnovice
Blick auf diese Artikel: Die Gefahren von Floating-Point. Obwohl die Beispiele sind in FORTRAN-es hat Sinn, für praktisch jede moderne Programmiersprache, einschließlich MATLAB. Ihr problem (und Lösung) ist beschrieben in "Sichere Vergleiche" Abschnitt.
Archivierten version von diese ausgezeichnete Ressource!
InformationsquelleAutor Rorick
Typ
Dieser Befehl wird Ihnen der VOLLE Wert der Zahl. Es ist wahrscheinlich etwas wie 24.00000021321 != 24.00000123124
InformationsquelleAutor KitsuneYMG
Schreiben versuchen
Achtung: Sie könnten überrascht sein über das Ergebnis!
Dies ist, weil 0.1 kommt mit einigen floating-point-Fehler, und wenn man drei solcher Bestimmungen zusammen, die Fehler nicht unbedingt bis 0 hinzufügen. Das gleiche Problem verursacht (floating) 24 nicht genau gleich sein (andere schwimmende) 24.
InformationsquelleAutor Andrey Rubshtein
Vielleicht sind die beiden zahlen sind wirklich 24.0 und 24.000000001 aber Sie sehen nicht alle Nachkommastellen.
InformationsquelleAutor Jimmy J
Check-out die Matlab EPS-Funktion.
Matlab verwendet floating point math bis zu 16 stellen Genauigkeit (nur 5 werden angezeigt).
InformationsquelleAutor jle