Campo de bits (C++)

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 6 de octubre de 2014; las comprobaciones requieren 48 ediciones .

Campo de bits ( campo de bits ing.  ) en programación  : una cantidad de bits dispuestos secuencialmente en la memoria , cuyo valor el procesador no puede leer debido a las peculiaridades de la implementación del hardware . .

Acerca de las implementaciones de hardware

Si se requiere leer el valor escrito en la ubicación de memoria , el procesador realiza las siguientes acciones:

El valor de lectura es igual al valor en la ubicación de memoria especificada y tiene un tamaño igual al ancho del bus de datos ( tamaño de palabra de la máquina ).

El ancho del bus de direcciones determina el tamaño mínimo de memoria direccionable . El controlador de memoria requiere que la dirección de la celda esté alineada con un límite de palabra de máquina .

Si el ancho de bits (número de bits) del valor a leer (de un campo de bits) no es igual al tamaño de la palabra de la máquina , después de leer la palabra de la máquina de la memoria , se deben ejecutar instrucciones adicionales :

Ejemplo. Dejar:

0011 0100 1010 11 10 01 00 0111 0100 1100 2
  1. El procesador leerá de la memoria una palabra de máquina igual al valor original:
0011 0100 1010 11 10 01 00 0111 0100 1100 2
  1. La instrucción and establecerá los bits que no están en el campo de bits en 0. Resultado:
0000 0000 0000 00 10 01 00 0000 0000 0000 2
  1. La instrucción shr desplazará los bits del campo de bits de izquierda a derecha para que el bit menos significativo del campo de bits se convierta en el bit menos significativo de la palabra de máquina . Resultado:
0000 0000 0000 0000 0000 0000 0000 1001 2

Si la dirección del valor que se va a leer de la memoria no está alineada con un límite de palabra de máquina , se requieren pasos adicionales:

Ejemplo. Dejar:

0011 0100 1010 1110 0100 011 1 0100 1100 2 0011 01 00 1010 1110 0100 0111 0100 1100 2
  1. El procesador leerá de la memoria dos palabras de máquina que contengan los bits deseados; los valores son iguales al original:
0011 0100 1010 1110 0100 011 1 0100 1100 2 0011 01 00 1010 1110 0100 0111 0100 1100 2
  1. Con la ayuda de dos instrucciones and , los bits no incluidos en el campo de bits se escribirán con los valores 0. Resultado:
0000 0000 0000 0000 0000 000 1 0100 1100 2 0011 01 00 0000 0000 0000 0000 0000 0000 2
  1. Con la ayuda de la instrucción, los shr bits de la segunda palabra de máquina se desplazarán de izquierda a derecha para que el bit menos significativo del campo de bits se convierta en el bit menos significativo de la palabra de máquina . Con la ayuda de la instrucción, los shl bits de la primera palabra de máquina se desplazarán de derecha a izquierda para que los bits menos significativos se liberen para los bits de la segunda palabra de máquina (para el siguiente paso). Resultado:
0000 0000 0000 0000 0 101 0011 00 00 0000 2 0000 0000 0000 0000 0000 0000 00 00 1101 2
  1. Con la ayuda de una instrucción, los or bits de dos palabras de máquina se "superpondrán" uno encima del otro. Resultado:
0000 0000 0000 0000 0 101 0011 0000 1101 2

Los pasos adicionales descritos se pueden realizar:

Desventaja: los comandos adicionales ralentizan la ejecución del programa . Ventaja: al usar campos de bits, se logra el empaquetamiento de información más denso .

Acerca de los compiladores

Los compiladores generalmente solo permiten las siguientes operaciones en campos de bits:

El campo de bits en sí mismo es tratado por el compilador como un número sin signo . El orden de los campos de bits en la estructura de datos depende de la plataforma de hardware y la implementación del compilador : algunos compiladores ubican los campos de bits comenzando por los bits menos significativos, mientras que otros los ubican por los más significativos.

Aplicación

Los campos de bits se utilizan para el empaquetado más completo de información , si la velocidad de acceso a esta información no es importante. Por ejemplo, para aumentar el ancho de banda del canal al transmitir información a través de la red o para reducir el tamaño de la información durante el almacenamiento. Además, el uso de campos de bits está justificado si el procesador admite instrucciones especializadas para trabajar con campos de bits y el compilador usa estas instrucciones al generar código de máquina .

Por ejemplo, en máquinas con una palabra de 32 bits , todos los campos en un paquete IPv4 (excepto los campos "dirección del remitente" y "dirección de destino") serán campos de bits, ya que su tamaño no es de 32 bits y sus direcciones no son un múltiplo de 4 bytes . Si, además, el procesador admite la lectura y escritura directa de números de 8 y 16 bits, los únicos campos de bits serán la versión, el tamaño del encabezado, DSCP , ECN , banderas y desplazamiento de fragmento.

Operaciones sobre campos multibit

Deje que haya cuatro campos de bits en un byte:

número de bit 7 [*1] 6 5 cuatro 3 2 una 0 [*2]
campo de bits d C b a
  1. El séptimo bit es el bit más significativo.
  2. El bit 0 es el bit menos significativo.

El valor de un número de ocho bits x , compuesto por campos de bits a , b , c y d , se puede calcular mediante la fórmula: (1) .

Si a=1 , b=0 , c=2=10 2 y d=5=0101 2 , x será .

Ensamblar un solo número a partir de campos de bits

Si el procesador opera con números binarios , la fórmula (1) puede optimizarse . Después de reemplazar las operaciones " exponenciación " por " desplazamiento lógico ", " suma " por " bit OR ", la fórmula (1) tomará la forma:

x = ( re << 4 ) | ( c << 2 ) | ( segundo << 1 ) | a

El desplazamiento lógico de un número binario es equivalente a multiplicar/dividir por un múltiplo de una potencia de dos: 2 1 =2, 2 2 =4, 2 3 =8, etc.

Extrayendo un campo de bits

Hay dos formas de obtener el valor v de algún campo de bits del número x :

  • v = ( x & mask_1 ) >> offset;
  • v = ( x >> offset ) & mask_2.

El primer método primero realiza una operación AND bit a bit , luego un desplazamiento lógico hacia la derecha. En el segundo método, las operaciones se realizan en orden inverso. La constante mask_2 se puede obtener de la constante mask_1 : . offset  es el número del primer bit menos significativo del campo de bits v , el exponente en la fórmula (1) .
mask_2 = mask_1 >> offset

Para obtener el valor de un campo de bits a partir del número x de la primera forma se realizan tres operaciones:

  1. calcule la "máscara de bits" mask_1  - un número que tiene unidades en los bits correspondientes al campo de bits y ceros en los bits restantes;
número de bit 7 6 5 cuatro 3 2 una 0
máscara para un 0 0 0 0 0 0 0 una
máscara para b 0 0 0 0 0 0 una 0
máscara para c 0 0 0 0 una una 0 0
máscara para d una una una una 0 0 0 0
  1. multiplique la "máscara de bits" por el número usando la operación " bit AND ";
  2. realizar un desplazamiento lógico a la derecha por bits de compensación .
campo de bits compensar
a 0
b una
C 2
d cuatro

Un ejemplo de cómo obtener un valor de un campo de bits c :

c = ( x & 00001100 b ) >> 2

Con el segundo método:

  1. realizar un desplazamiento lógico a la derecha;
  2. calcule la "máscara de bits" mask_2  : un número en el que los primeros n dígitos menos significativos se establecen en unos, y los dígitos restantes son ceros; n  es el número de dígitos del campo de bits;
número de bit 7 6 5 cuatro 3 2 una 0
máscara para un 0 0 0 0 0 0 0 una
máscara para b 0 0 0 0 0 0 0 una
máscara para c 0 0 0 0 0 0 una una
máscara para d 0 0 0 0 una una una una
  1. multiplique la "máscara de bits" por el número usando la operación " bit AND ".

Un ejemplo de cómo obtener un valor de un campo de bits c :

c = ( x >> 2 ) & 00000011b _

El campo de bits menos significativo (campo a en este ejemplo) no se desplaza lógicamente en bits cero. Ejemplo:
a = ( x & 00000001b ) >> 0
a = ( x >> 0 ) & 00000001b )

a = x & 00000001b _

En el segundo método, el campo más alto (el campo d en este ejemplo) no realiza la multiplicación lógica, ya que la operación lógica de desplazamiento a la derecha agrega cero bits al número. Ejemplo:
d = ( x >> 4 ) & 00001111b )

re = x >> 4

Sustitución de campo de bits

Para reemplazar un campo de bit, se realizan tres operaciones:

  1. se calcula una máscara, un número cuyos bits correspondientes al campo de bits tienen ceros;
  2. la operación " bit AND " multiplica el número x por la máscara; la operación realiza la puesta a cero en los bits correspondientes a la máscara;
  3. la operación " bit inclusivo OR " se usa para sumar el producto resultante y el número x desplazado por el número de bits correspondiente al desplazamiento del campo de bits desde el comienzo de la palabra.

Un ejemplo de reemplazo de un valor por un campo de bits d :

xnuevo = ( x & 00001111 b ) | ( re << 4 )

Operaciones en campos de un bit

Existen métodos más simples para trabajar con campos de bits que tienen un ancho de un bit.

Los campos de bits a y b ocupan un bit cada uno.

Comprobando un solo bit

Para obtener el valor de un solo bit, se realiza una multiplicación lógica (operación " bit AND ") del número x mediante una máscara que tiene un bit establecido, correspondiente a un bit de un campo de un bit. Si el resultado es 0, el bit es 0.

Un ejemplo de obtener el valor de un campo de un bit b :

b = ( ( x & 00000010 b ) != 0 )

Para verificar si uno o más bits del grupo son iguales a uno, se toma una máscara, en la que se establecen unidades en las posiciones de los bits verificados:

a_o_b = ( ( x & 00000011 b ) != 0 )

Para verificar si todos los bits del grupo son iguales a uno, use " Y bit a bit" y la operación " == " :

a_y_b = ( ( x & 00000011 b ) == 00000011 b )

Configuración de ritmos

Para configurar los bits, se realiza una suma lógica (la operación " bit OR ") del número x con una máscara que tiene configurados unos en las posiciones correspondientes al campo de bits.

Un ejemplo de configuración de un bit de un campo de un bit a :

x1 = x | 00000001b _

Para establecer varios bits del número x , por ejemplo, los bits de los campos de un bit a y b , use una máscara que tenga bits correspondientes a los bits de los campos de bits establecidos en unos:

x2 = x | 00000011b _

Eliminación de ritmos

Para establecer uno o más bits de ceros, el número x se multiplica por la operación " bit AND " de la máscara, en la que los bits cero se establecen en las posiciones correspondientes al campo de bits.

Un ejemplo de configuración de bits a cero en el campo de bits b :

x3 = x & 11111101b _

Cambio de ritmo

Para cambiar el valor de los bits al contrario (de 0 a 1 y de 1 a 0), se suma el número x mediante la operación “ OR exclusivo de bit ” con una máscara en la que las unidades se colocan en posiciones correspondientes a las posiciones de los bits de palanca.

Un ejemplo de cómo cambiar los valores de bits del campo de bits b :

x4 = x ^ 00000010b_ _

Operaciones sobre campos con signo en complemento a dos

En la memoria de la computadora, los enteros negativos se pueden codificar de una de las siguientes maneras:

La mayoría de los procesadores modernos implementan el tercer método. Considere la representación binaria de varios enteros en complemento a dos :

4 = 00000100 2 3 = 00000011 2 2 = 00000010 2 1 = 00000001 2 0 = 00000000 2 -1 = 11111111 2 -2 = 11111110 2 -3 = 11111101 2 -4 = 11111100 2 etc.

Deje que los campos c y d tengan el formato " código complementario ". Luego, el campo c puede almacenar números desde −2=10 2 hasta 1=01 2 , y el campo d puede almacenar números desde  −8=1000 2 hasta 7=0111 2 .

Montaje y sustitución de números

Cada uno de los términos (excepto el más alto), para no estropear los bits más altos, se debe multiplicar por una máscara de bits de la longitud adecuada. En particular:

x = (d << 4) + ((c & 00000011b) << 2) + (b << 1) + a

Extracción de números

Para extraer números, debe cambiar el campo por el número requerido de bits a la derecha, al mismo tiempo que multiplica el bit de signo. Por ejemplo, puede usar el cambio aritmético para hacer esto . Si x tiene 8 bits de largo, entonces

c = (x << 4 ) >>a 6 d = x >> un 4

¡Atención! En el lenguaje de programación Java , lo contrario es cierto: el signo denota un cambio aritmético y el signo denota  un cambio lógico . >>>>>

Si no hay cambio aritmético, entonces...

c1 = x >> 2 si (c1 y 00000010b ≠ 0) entonces c = c1 | 0x11111100b de lo contrario c = c1 y 0x00000011b

Declaraciones de campo de bits

En C y C++ , al declarar un campo de bits , se utiliza el carácter de dos puntos ( :) . Los dos puntos van seguidos de una expresión constante que determina el número de bits en el campo de bits [1] . Ejemplo:  

estructura rgb { r sin signo : 3 ; sin signo g : 3 ; sin signo b : 3 ; };

Véase también

Notas

  1. Ray Lishner. C++. Referencia = C++ En pocas palabras / Cap. edición E. Strogonova. - San Petersburgo. : Pedro , 2003 . - S. 193. - 907 pág. - 3500 copias.  - ISBN 5-94723-928-0 , BBC 32.973-018.1ya22, UDC 681.3.06(03).