paint-brush
Cómo manipular bits en C y C++por@botman1001
29,534 lecturas
29,534 lecturas

Cómo manipular bits en C y C++

por Abhishek Singh Thakur3m2019/12/04
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

En el lenguaje de programación C++, el tipo de datos int es de 16 bits, 32 bits y 64 bits. En programación, un número entero de n bits se almacena como un número binario que consta de n bits. En una representación con signo, el primer bit representa el signo de un número (0 para positivo y 1 para negativo), y los n-1 bits restantes contienen la magnitud del número. En una representación sin signo, el siguiente número después del primer bit es par y si es impar. Podemos usar el operador & para comprobar si un número es par o impar.
featured image - Cómo manipular bits en C y C++
Abhishek Singh Thakur HackerNoon profile picture

Todos los datos en la computadora se representan en binario, es decir, en 0 o 1. Las computadoras o máquinas no entienden nuestros idiomas, entienden bits. Generalmente, al programador no le importan las operaciones a nivel de bit. Pero a veces un programador tiene que sumergirse en un nivel más profundo y trabajar en bits.

Representación de bits

En programación, un número entero de n bits se almacena como un número binario que
consta de n bits. Entonces, un entero de 32 bits consta de 32 bits y 64 bits
entero consta de 64 bits. En lenguaje de programación C++ tipo de datos int
es de 16 bits, 32 bits y 64 bits. ver aquí

Aquí está la representación de bits de 32 bits int número 10:
000000000000000000000000000001010

En C++,

 int
está firmado o no , por lo que una representación de bits está firmada o no .

En una representación con signo, el primer bit representa el signo de un número (0
para positivo y 1 para negativo), y los n-1 bits restantes contienen el
magnitud del número.

Existe una conexión entre una representación firmada y una no firmada. un numero firmado

 -x
es igual a un número sin signo
 2^n – x
.

 -x (signed) = 2^n - x (unsigned)

 int a = -10 ; unsigned int b = a; std :: cout << a << "\n" ; /* -10 */ std :: cout << b << "\n" ; /* 4294967286 */

En una representación firmada, el siguiente número después de

 2^(n – 1) – 1
es
 -2^n – 1
, y en una representación sin signo, el siguiente número después de
 2^n – 1
es
 0
.

operaciones de bits

Podemos usar el operador & para comprobar si un número es par o impar. Si

 x & 1 = 0
después
 x
es par y si
 x & 1 = 1
después
 x
es impar. También podemos decir que,
 x
es divisible por
 2^k
Exactamente cuando
 x & (2^k – 1) = 0.

 x<<k
corresponde a multiplicar
 x
por
 2^k
, y
 x>>k
corresponde a dividir
 x
por
 2^k
redondeado a un entero.

Tareas comunes de bits

Representación binaria de unsigned int :

 void binary ( unsigned int num) { for ( int i = 256 ; i > 0 ; i = i/ 2 ) { if (num & i) std :: cout << "1 " ; else std :: cout << "0 " ; } std :: cout << std :: endl ; }

Bit de ajuste en la posición :

 int set_bit ( int num, int position) { int mask = 1 << position; return num | mask; }

Obtener Bit en la posición :

 bool get_bit ( int num, int position) { bool bit = num & ( 1 << position); return bit; }

Bit de limpieza en la posición :

 int clear_bit ( int num, int position) { int mask = 1 << position; return num & ~mask; }

Representando Conjuntos

Los bits de representación de un número entero están indexados en 0 y el índice comienza desde el lado derecho, es decir, el bit menos significativo. Entonces podemos representar cada subconjunto del conjunto

 {0, 1, 2, ..., n-1}
como un entero de n bits y cuyos bits indican qué elemento pertenece al subconjunto. Si el bit en el índice 3 es 1 y en el índice 4 es 0 en la representación binaria de un número, entonces 3 pertenece al subconjunto y 4 no pertenece al subconjunto.

Para un entero de 32 bits, el conjunto es {0, 1, 2,…, 31} y el subconjunto es {1, 3, 4, 8}. La representación binaria del conjunto es:
000000000000000000000000100011010
y la representación decimal es 2^8 + 2^4 + 2^3 + 2^1 = 282.

Código para formar un subconjunto y agregarle elementos:

 int add_elements_to_subset () { int subset = 0 ; subset = subset | ( 1 << 1 ); subset = subset | ( 1 << 3 ); subset = subset | ( 1 << 4 ); subset = subset | ( 1 << 8 ); return subset; }

Código para imprimir elementos del subconjunto:

 void printing_subset ( int subset) { for ( int i = 0 ; i < 32 ; i++) { if (subset & ( 1 << i)) std :: cout << i << " " ; } }

Funciones adicionales

El compilador g++ proporciona las siguientes funciones para contar bits:

 __builtin_clz(x)
: el número de ceros al principio del número

 __builtin_ctz(x)
: el número de ceros al final del número

 __builtin_popcount(x)
: el número de unos en el número

 __builtin_parity(x)
: la paridad (par o impar) del número de unos

Publicado originalmente en ProgrammerCave

 Reference:
 Competitive Programmer's Handbook, by Antti Laaksonen