2017-08-30 7 views
-1

Je me demande si quelqu'un pourrait expliquer à mon pourquoi & comment ce code fonctionne, pour convertir un double entre -1,0, et +1,0, à un entier de 14 bits.Pourquoi et comment fonctionne ce "double" pour le code "14 bits Int"?

Comment les valeurs ont-elles été choisies dans data14, et que se passe-t-il dans les coulisses?

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

Comprenez-vous ce que sont les changements de bits et le masquage des bits? Si non, apprenez-en d'abord, puis revenez à ceci. OK, bien maintenant? Il peut être utile de comprendre ce code si vous gardez à l'esprit que la décimale 16383 est hexadécimale 0x3FFF, qui est le binaire 11111111111111, c'est-à-dire 14 bits consécutifs. Il serait également utile d'utiliser votre débogueur pour regarder les octets bruts de 'data14' pour n'importe quelle valeur donnée de' data', faites le calcul pour comprendre pourquoi 'data14' est réglé comme il le fait (par exemple,' 0.5' -> '12287' aka' 0x2FF'), et travailler sur papier pourquoi le décalage de bit est fait comme il est. –

+1

Si ça aide: '-1.0' devient' 0' et '1.0' devient' 16383' ('0x3FFF', ie 14 bits maximum). Le code traduit des valeurs à virgule flottante comprises entre '-1.0..1.0' et des valeurs décimales comprises entre' 0..16383'. –

+0

Quel est le raisonnement derrière l'ajout de 1 aux données, multipliant 14 bits (0x3FFF) par deux, puis ajouter 0,5? – Nop

Répondre

1

Si vous pouvez analyser l'ordre des opérations, voici le résultat de la séquence en terme d'intervalle de données

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] 

Notez que en terme de densité de probabilité, une distribution uniforme des données dans [-1, 1] donnerait une distribution biaisée dans [0, 16383] - les valeurs extrêmes 0 et 16383 ayant deux fois moins de probabilité d'occurrence que [1,16382].

Peut-être que cela est nécessaire, sinon il faudrait multiplier par le prédécesseur à virgule flottante de 16384 et éviter d'ajouter +0,5.

+1

Je pense qu'une meilleure alternative à la polarisation d'adresse par rapport aux extrémités serait de retarder le serrage jusqu'à * après * l'addition de "0,5", car l'arrondi est réellement souhaitable dans cette conversion. – njuffa