Sind in MATLAB Variablen standardmäßig doppelt korrekt?
Diese Frage stellte sich auch etwas seltsam, dass ich bemerkte nach der Untersuchung diese Frage weiter...
Ich immer verstanden MATLAB-Variablen werden double-precision standardmäßig. Also, wenn ich etwas zu tun, wie eine variable deklarieren, die mit 20 stellen nach dem Komma:
>> num = 2.71828182845904553488;
>> class(num) %# Display the variable type
ans =
double
Ich würde erwarten, dass die letzten 4 Ziffern werden ignoriert, da die floating-point relative Genauigkeit in der Größenordnung von 10-16:
>> eps(num)
ans =
4.440892098500626e-016
Wenn ich versuche, um die Anzahl mit mehr als 16 stellen nach dem Komma (entweder FPRINTF oder SPRINTF), ich bekomme, was ich erwarte, um zu sehen:
>> fprintf('%0.20f\n',num)
2.71828182845904550000
>> sprintf('%0.20f',num)
ans =
2.71828182845904550000
In anderen Worten, Ziffern 17 bis 20 sind alle 0.
Aber die Dinge seltsam, wenn ich den pass num
zu den variable precision-Arithmetik-Funktion in der Symbolische Toolbox, sagt er zu repräsentieren Sie die Nummer mit 21 digits of precision:
>> vpa(num,21)
ans =
2.71828182845904553488
WAS?! Die letzten 4 Ziffern wieder aufgetaucht! Sollten Sie nicht verloren, wenn die ursprüngliche Zahl, die ich eingegeben wurde gespeichert als double-precision-variable num
? Da num
ist eine double-precision-variable, wenn es übergeben wird, um vpa
, wie hast vpa
wissen, was Sie waren?
Meine beste Vermutung, was passiert ist, dass MATLAB intern repräsentiert num
mit mehr Präzision als eine doppelte, da ich initialisiert es auf eine Zahl mit mehr Ziffern hinter dem Komma als eine double-precision-variable umgehen konnte. Ist das wirklich das, was passiert ist, oder etwas anderes?
BONUS: Und hier ist eine weitere Quelle der Verwirrung, wenn Sie nicht bereits über eine Migräne aus den oben genannten...
>> num = 2.71828182845904553488; %# Declare with 20 digits past the decimal
>> num = 2.718281828459045531; %# Re-declare with 18 digits past the decimal
>> vpa(num,21)
ans =
2.71828182845904553488 %# It's the original 20-digit number!!!
InformationsquelleAutor der Frage gnovice | 2010-11-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie verdoppelt. Vpa() ist einfach die Auswahl zu zeigen nicht-signifikante Ziffern über die floating-point-relative Genauigkeit, wobei printf() und disp() truncate oder null heraus.
Du bist nur immer Ihre ursprünglichen vier Ziffern wieder raus, da die wörtliche, die Sie wählten zu initialisieren num mit der gerade geschieht, werden die genauen Nachkommastellen einer double binary Wert, denn es war kopieren und einfügen aus der Ausgabe der Erweiterung eines aktuellen double-Wert aus der anderen Frage. Es wird nicht die Arbeit für andere in der Nähe-Werte, wie Sie in der show "BONUS" Nachtrag.
Genauer gesagt, alle numerischen Literale in Matlab erzeugen Werte vom Typ double. Sie bekommen Umgerechnet auf die binary double-Wert, der am nächsten zu dem dezimal-Wert, den Sie repräsentieren. Im Effekt, Ziffern buchstäblich über die Grenze der Genauigkeit der double-Typ ist, wird kommentarlos gelöscht. Wenn Sie kopieren und einfügen der Ausgabe des vpa eine neue variable erstellen, wie die andere Frage, die der poster hat mit dem "e = ..." Anweisung, du bist der Initialisierung einen Wert aus einem literal, statt sich direkt mit dem Ergebnis des vorherigen Ausdrucks.
Die Unterschiede sind hier nur in der Ausgabe formatieren. Ich denke, was passiert ist, dass vpa (), double precision binary double und behandeln Sie es als einen exakten Wert. Für eine gegebene binäre Mantisse-exponent-Wert, berechnen Sie die Dezimalzahl auf beliebig viele Nachkommastellen. Wenn Sie haben eine begrenzte Genauigkeit ("Breite") in den binären Wert, wie Sie tun, mit einer festen Größe Daten geben, nur so viele Dezimalstellen von Bedeutung sind. Sprintf() und Matlab-Standard-display bedienen Sie dieses durch Rundung der Ausgabe oder Anzeige von nicht-signifikante Ziffern als 0. Vpa() ignoriert die Grenzen der Präzision und Weiterbildung zu berechnen, wie viele Dezimalstellen, wie Sie verlangen.
Diese zusätzlichen Ziffern sind falsch, in dem Sinne, dass, wenn Sie wurden ersetzt durch andere Werte zu produzieren ein in der Nähe dezimal-Wert, würden Sie alle bekommen "gerundet" auf die gleiche binary double-Wert.
Hier ist ein Weg, es zu zeigen. Diese Werte von x sind alle die gleichen, wenn gelagert in Doppel -, und alle vertreten die gleiche von vpa().
Hier ist eine andere Art zu demonstrieren. Hier sind zwei Doppelzimmer, die sehr sind nah zu einander.
Vpa(x0) und vpa(x1) sollten Ausgaben erzeugen, die Verschieden viel Vergangenheit die 16 stellige. Allerdings sollten Sie nicht in der Lage sein zu erstellen, die einen double-Wert x, so dass vpa(x) erzeugt eine dezimale Darstellung, fällt zwischen vpa(x0) und vpa(x1).
(UPDATE: Amro Punkte aus, die Sie verwenden können
fprintf('%bx\n', x)
anzuzeigen eine genaue Darstellung der zugrunde liegenden binären Wert in hex-format. Sie können diese verwenden, um zu bestätigen, die map-Literale auf die gleiche Doppel.)Ich vermute, vpa() auf diese Weise verhält, weil Sie mit Ihren Eingaben als genaue Werte, und polymorph unterstützt andere Matlab-Typen aus der Symbolic Toolbox, dass mehr Präzision als verdoppelt. Diese Werte müssen initialisiert werden, indem andere Mittel als numerische Literale, die ist, warum sym() nimmt einen string als Eingabe und "vpa(exp(1))" unterscheidet sich von "vpa(sym('exp(1)'))".
Sinn? Sorry für die lange-windedness.
(Hinweis: ich habe nicht die Symbolic Toolbox, also kann ich nicht testen, vpa (mich.)
InformationsquelleAutor der Antwort Andrew Janke