Ich habe eine Inkonsistenz für uint64
entdeckt, wenn ich Vektoren in Matlab verwende. Es scheint, als ob ein Array von Uint64 nicht für alle 64 Bits exakt ist. Dies gab nicht die erwartete Ausgabe,
Jedoch
%Vor%tut es. Es funktioniert auch mit
%Vor%Beim Arbeiten mit unsigned integers erwartet man ein spezielles Verhalten und in der Regel auch eine perfekte Genauigkeit. Das wirkt komisch und sogar ein bisschen unheimlich. Ich sehe dieses Problem nicht mit kleineren Zahlen. Vielleicht weiß jemand mehr? Ich erwarte nicht, dass dies ein unbekanntes Problem ist, also denke ich, dass es eine Erklärung dafür geben muss. Ich wäre gut zu wissen, warum das passiert und wann, um es zu vermeiden. Wie immer wird diese Art von Problemen nirgends in der Dokumentation erwähnt.
Matlab 2014a, Windows 7.
BEARBEITEN
Es ist erwähnenswert, dass ich dasselbe Verhalten bei der direkten Definition von Arrays sehen kann.
%Vor%Dies ist die Wurzel, warum ich diese Frage stelle. Ich habe eine Lösung für diesen Fall schwer zu sehen.
Obwohl es vielleicht überraschend ist, ist dies ein Gleitkomma-Genauigkeits-Problem. : -)
Die Sache ist, alle numerischen Literale haben standardmäßig den Typ double
in MATLAB; Deshalb:
gibt true
zurück; Die Gleitkommadarstellung in doppelter Genauigkeit von 13286492335502040542
ist 13286492335502041088
. Da p
die Klasse uint64
hat, werden alle Zuweisungen, die daran vorgenommen werden, die rechte Seite in ihre Klasse umwandeln.
Andererseits wird der uint64(13286492335502040542)
"Aufruf" vom MATLAB-Interpreter optimiert, um den Overhead beim Aufrufen der uint64
-Funktion für das double
-Argument zu vermeiden, und konvertiert das Literal direkt in seine vorzeichenlose Ganzzahldarstellung (was genau ist).
Bei einer dritten Hand gilt die Funktionsanrufoptimierung nicht für
%Vor%, weil das Argument von uint64
kein Literal ist, sondern das Ergebnis eines Ausdrucks, d. h. das Ergebnis des vertcat
-Operators, der auf zwei double
-Operanden angewendet wird. In diesem Fall ist der MATLAB-Interpreter nicht schlau genug, um herauszufinden, dass die beiden Funktionsaufrufe "pendeln" sollten (die Verkettung von Uint sollte die gleiche wie die der Verkettung sein), also wertet er die Verkettung aus (die ein Array mit gleichem% co_de ergibt) % weil FP-Genauigkeit), konvertiert dann die zwei ähnlichen double
-Werte in double
.
TLDR: der Unterschied zwischen
%Vor%und
%Vor%ist ein Nebeneffekt der Funktionsaufrufoptimierung.
Matlab liest, wenn nicht anders angegeben, Zahlen als Double und wandelt dann den entsprechenden Datentyp um. Der Matlab - double -Datentyp erlaubt 51 Bits für den Gleitkommafraktion und gibt den Möglichkeit, 52-Bit-Ganzzahlen ohne Verlust der Vorbelegung (Mantisse) zu speichern. Beachten Sie, dass 13286492335502041088
nur 13286492335502040543
ist und die letzten 12 Bits auf Null gesetzt sind.
Die Lösung, wie Sie gesagt haben, besteht darin, die Literale direkt uint64(13286492335502040543)
zu konvertieren.
p=uint64([13286492335502040542;13286492335502040543])
funktioniert nicht, weil es ein doppeltes Array erstellt und es dann in uint64 konvertiert
Dieses Problem wird in der uint64 Dokumentation unter "More About" erwähnt, obwohl dies der Fall ist erwähnt nicht, dass Nebenstellen als Doppel gelesen werden, wenn nicht anders angegeben.
Tags und Links matlab