2012-06-04 25 views
5

Así que estoy leyendo un número entero de 12 bits de una matriz de bytes. Ese número puede ser negativo, pero no puedo imaginar cómo convertirlo en una variable utilizable int16/int32 en C#. Tengo la sensación de que tendré que hacer algo con cambios de bit u otras operaciones a nivel de bits, pero hasta ahora he estado atacando. Alguien me puede apuntar en la dirección correcta.Convertir 12 bit int a 16 o 32 bits

var x = 0xFFF;

Esto debe imprimirse como -1, pero C# arroja naturalmente a un int32 e imprime como 4095. Si esto se debe convertir a int16 o int32, ¿cómo puedo conservar el valor negativo?

Respuesta

13

de 32 bits:

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

¡Funciona muy bien, muchas gracias! ¿Mente explicando qué está pasando aquí? sé lo que es el >>^| hacer pero no comprender del todo. – Clarke76

+2

Básicamente cambiando a la derecha hasta que solo quede el bit de signo. Si es cero, simplemente devolvemos el valor original. Si es 1, tomamos -1 (0xFFFFFFFF), desactivamos los 12 bits más bajos ('xor'), luego' o' con el valor original para activar los bits en él. El resultado es básicamente activar los 20 bits superiores del valor de 32 bits. –

+0

sí ... terminé escribiendo todo en papel y viendo exactamente lo que estaba pasando. Eso realmente ayudó. Obtuve que el último bit se usaría como indicador de negativo. Después de eso, fue fácil de seguir. Gracias de nuevo. – Clarke76

8

extensión de signo sin condicionales, asumiendo x es una que ya contiene el valor de 12 bits corto con signo:

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

Los paréntesis son puramente para la comprensión de lo que está pasando. Los cambios de bit son asociativos de izquierda como otros operadores aritméticos y lógicos. El motivo por el que esto funciona es que >> es un desplazamiento aritmético hacia la derecha para tipos con signo. Eso significa que, en lugar de desplazarse en ceros en el bit más significativo, duplica el MSB tantas veces como sea necesario.

extensión sesión en general de n bit a bit m sería entonces:

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

Por razones obvias m se limitaría a 8 para sbyte, 16 para short, 32 para int y 64 para long. Nuevamente, los paréntesis son puramente cosméticos. La resta se une más apretada que los cambios de bit.

0

Detecta el bit de señal y amplíalo. Para 16 bits:

x = (x & 0x800 ? x^0xf000 : x); 
Cuestiones relacionadas