2017-08-30 5 views
-1

Ich frage mich, wenn jemand könnte bitte erklären, warum &, wie dieser Code funktioniert, um ein Doppel zwischen -1.0 und +1.0, um eine 14-Bit-Ganzzahl zu konvertieren.Warum & Wie funktioniert dieser "Doppel" - "14-Bit Int" -Code?

Wie wurden die Werte in data14 ausgewählt und was passiert hinter den Kulissen?

double data = 0.5; 

if (data < -1.0) { 
    data = -1.0; 
} else if (data > 1.0) { 
    data = 1.0; 
} 

int data14 = (int)((data+1.0)/2.0*16383 + 0.5); 

BYTE upper7 = data14 >> 7; 
BYTE lower7 = data14 & 0x7f; 
+1

Verstehen Sie, was Bitverschiebung und Bitmaskierung sind? Wenn nicht, lerne zuerst diese und dann zurück. OK, gut jetzt? Es kann hilfreich sein, diesen Code zu verstehen, wenn man bedenkt, dass Dezimal 16383 hex 0x3FFF ist, was binär 11111111111111 ist, dh 14 aufeinanderfolgende Bits. Es würde auch helfen, Ihren Debugger zu benutzen, um die rohen Bytes von 'data14' für einen gegebenen Wert von' data' zu betrachten, die Mathematik zu verstehen, warum 'data14' so eingestellt wird, wie es funktioniert (zB' 0.5' -> '12287' aka' 0x2FF'), und erarbeiten Sie auf dem Papier, warum das Bit-Shifting so durchgeführt wird, wie es ist. –

+1

Wenn es hilft: '-1.0' wird zu" 0 "und' 1.0' wird zu '16383' (' 0x3FFF', dh maximal 14 Bit). Der Code übersetzt Gleitkommawerte zwischen -1.0..1.0 und Dezimalwerte zwischen 0..16383. –

+0

Was ist der Grund für das Hinzufügen von 1 zu Daten, das Multiplizieren von 14 Bits (0x3FFF) mit zwei und dann das Addieren von 0,5? – Nop

Antwort

1

Wenn Sie die richtige Reihenfolge der Vorgänge analysieren kann, hier ist das Ergebnis der Sequenz in der Bezeichnung des Datenintervalls

input data    -> (-inf,inf) 
if(...) else if() ... -> [-1 , 1] 
data+1     -> [0 , 2] 
/2      -> [0 , 1] 
*16383     -> [0 , 16383] 
+0.5     -> [0.5 , 16383.5] 
int()     -> [0 , 16383] 

Beachten Sie, dass in der Bezeichnung der Dichte der Wahrscheinlichkeit, eine gleichmäßige Verteilung von Daten in [-1, 1] würde eine verzerrte Verteilung in [0, 16383] ergeben - die Extremwerte 0 und 16383 hätten eine doppelt so geringe Eintrittswahrscheinlichkeit wie [1,16382].

Vielleicht ist das gewünscht, sonst wäre es notwendig, mit dem Gleitkomma-Vorgänger von 16384 zu multiplizieren und das Hinzufügen von +0,5 zu vermeiden.

+1

Ich denke, eine bessere Alternative zur Vorspannung gegen die Endpunkte wäre, die Klemmung bis * nach der Addition von '0,5' zu verzögern, da eine Rundung bei dieser Umwandlung tatsächlich wünschenswert ist. – njuffa