2012-06-04 14 views
5

Quindi sto leggendo un intero a 12 bit da un array di byte. Quel numero può essere negativo ma non riesco a capire come convertirlo in una variabile utilizzabile int16/int32 in C#. Ho la sensazione che avrò bisogno di fare qualcosa con lo spostamento di bit o altre operazioni bit a bit, ma mi sono battuto fino ad ora. Qualcuno può indicarmi la giusta direzione.Converti 12 bit int a 16 o 32 bit

var x = 0xFFF;

Questo deve essere stampato come -1 ma C# esegue naturalmente il cast di un int32 e viene stampato come 4095. Se è necessario eseguire il cast su int16 o int32, come mantenere il valore negativo.

risposta

13

a 32 bit:

x = (x >> 11) == 0 ? x : -1^0xFFF | x; 
+0

Funziona alla grande, grazie mille! Spiega che cosa sta succedendo qui? so cosa sono >>> | fare ma non del tutto comprensibile. – Clarke76

+2

Fondamentalmente spostando verso destra fino a quando rimane solo il bit del segno. Se è zero, restituiamo solo il valore originale. Se è 1 allora prendiamo -1 (0xFFFFFFFF), disattiviamo i 12 bit inferiori ('xor'), quindi' or' con il valore originale per attivare i bit in esso. In pratica, il risultato è semplicemente l'attivazione dei 20 bit superiori del valore a 32 bit. –

+0

sì ... ho finito per scrivere tutto su carta e vedere esattamente cosa stava succedendo. Questo mi ha davvero aiutato. Ho capito che l'ultimo bit sarebbe stato usato come una bandiera negativa. Dopo che è stato facile da seguire. Grazie ancora. – Clarke76

8

Segno interno senza condizionali, assumendo x è una che contiene già il valore di 12 bit breve firmato:

x = (x << 4) >> 4; 

Le parentesi sono puramente per capire cosa sta succedendo. I bit shift sono associativi a sinistra come altri operatori aritmetici e logici. Il motivo per cui questo funziona è che >> è uno spostamento a destra aritmetico per i tipi firmati. Ciò significa che, invece di spostare gli zeri al bit più significativo, duplica l'MSB tutte le volte necessarie.

Entra estensione in generale da n bit a bit m sarebbe allora:

x = (x << (m - n)) >> (m - n); 

Per ovvie ragioni m sarebbe limitato a 8 per sbyte, 16 per short, 32 per int e 64 per long. Ancora una volta, le parentesi sono puramente estetiche. La sottrazione si lega più strettamente dei bit shift.

0

Rileva il bit di segno ed estendilo. Per 16-bit:

x = (x & 0x800 ? x^0xf000 : x); 
Problemi correlati