2012-10-02 14 views
12

Estoy leyendo algunos valores de un solo byte. Me dijeron en el manual del usuario que este byte contiene 3 valores diferentes. Hay una mesa que tiene este aspecto:C#, bits y bytes - ¿Cómo recupero los valores de bit de un byte?

bit table

interpreto que la precisión tiene significado ocupa 3 bits, escala ocupa 2 y tamaño ocupa 3 para un total de 8 (1 byte).

Lo que no tengo claro es:

1 - ¿Por qué es etiquetada 7 a 0 en vez de 0 a 7 (algo que ver con la significación tal vez?)

2 - ¿Cómo extraigo los valores individuales de ese byte?

Respuesta

17

es costumbre numerar los bits en un byte según su significado: el bit x representa 2^x. De acuerdo con este esquema de numeración, el bit menos significativo obtiene el número cero, el siguiente bit es el número uno, y así sucesivamente.

Conseguir bits individuales requiere un cambio y una operación de enmascaramiento:

var size = (v >> 0) & 7; 
var scale = (v >> 3) & 3; 
var precision = (v >> 5) & 7; 

Shift por el número de bits a la derecha de la parte más a la derecha que usted necesita para (desplazando por cero se ignora; he añadido para fines ilustrativos).

máscara con el número más alto que se ajusta en el número de bits que le gustaría conseguir: 1 para un bit, 3 de dos bits, 7 de tres bits, 2^x-1 para x bits.

+0

Gracias por la explicación de cómo funciona el número de máscara también. – bugfixr

+0

Pruebe los operadores a la inversa: var size = ((v & 7) >> 0); var scale = ((v & 28) >> 3); var precision = ((v & 224) >> 5); – Robetto

3

1. Sí, el bit más significativo generalmente se escribe primero. El bit situado más a la izquierda tiene la etiqueta 7 porque cuando el byte se interpreta como un entero, ese bit tiene el valor 2 (= 128) cuando se establece.

Esto es completamente natural y, de hecho, es exactamente lo mismo que escribir números decimales (el dígito más significativo primero). Por ejemplo, el número 356 es (3 x 10 ) + (5 x 10 ) + (6 x 10 ).

2. Para finalizar, como se ha mencionado en otras respuestas se pueden extraer los valores individuales mediante el desplazamiento de bits y el bit a bit y los operadores de la siguiente manera:

int size = x & 7; 
int scale = (x >> 3) & 3; 
int precision = (x >> 5) & 7; 

Nota importante: esto supone que los valores individuales son a ser interpretado como enteros positivos. Si los valores pueden ser negativos, esto no funcionará correctamente. Teniendo en cuenta los nombres de sus variables, es poco probable que esto sea un problema aquí.

+0

Cada uno de nosotros respondimos diferente mitades de la pregunta. ¿Dividimos un voto positivo o algo así? : D – Wug

4
  1. Potayto, potahto.

  2. tendrá que utilizar los turnos y máscaras para aplanar los bits no deseados, tales como:

    byte b = something; // b is our byte 
    
    int size = b & 0x7; 
    int scale = (b >> 3) & 0x3; 
    int position = (b >> 5) & 0x7; 
    
1

Puede hacerlo a través de la aritmética bit a bit:

uint precision = (thatByte & 0xe0) >> 5, 
    scale = (thatByte & 0x18) >> 3, 
    size = thatByte & 7; 
6

Usted puede hacer cambios y máscaras, o puede utilizar la clase BitArray: http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx

Ejemplo con BitVector32:

BitVector32 bv = new BitVector32(0); 

var size = BitVector32.CreateSection(7); 
var scale = BitVector32.CreateSection(3, size); 
var precision = BitVector32.CreateSection(7, scale); 

bv[size] = 5; 
bv[scale] = 2; 
bv[precision] = 4; 

salida LINQPad:

LINQPad output

+0

+1 para señalar una alternativa que no se remonta a los días de C: P [BitVector32] (http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32.aspx) es otra opción, que también le permite dividir su campo de bits en secciones (correspondientes al tamaño, escala y precisión del OP) y asignarlas o leerlas directamente usando la sintaxis de indexación. – shambulator

+0

Esta es una respuesta de enlace. – Wug

Cuestiones relacionadas