uint64 ist nicht genau für Vektoren in Matlab

8

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,

%Vor%

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.

    
patrik 04.01.2016, 12:50
quelle

3 Antworten

10

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:

%Vor%

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.

    
user2271770 04.01.2016, 13:47
quelle
7

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.

    
pseudoDust 04.01.2016 13:39
quelle
0

Ich stimme zu, das scheint seltsam und ich habe keine Erklärung. Ich habe einen Workaround:

%Vor%

, d. h., wirf die separaten Werte auf uint64 s.

    
Tom 04.01.2016 13:37
quelle

Tags und Links