Operador de cambio de bits en C++

Anam Javed 12 octubre 2023
  1. Operador de desplazamiento de bits a la izquierda en C++
  2. Operador de desplazamiento de bits a la derecha en C++
  3. Cambio de bit en el tipo de datos flotante en C++
  4. Cambio de bits en Array en C++
  5. Desplazamiento de bits y máscara en C++
  6. Cambio de bits para números negativos en C++
  7. Cambio de bits usando Long en C++
  8. Conclusión
Operador de cambio de bits en C++

En C++, los operadores de cambio de bits hacen lo que su nombre sugiere, cambiar bits. De acuerdo con los requisitos del programa, un operador de desplazamiento bit a bit desplaza los bits binarios hacia la izquierda o hacia la derecha.

Se aplican valores enteros a estos operadores (int, long, posiblemente short y byte o char). En algunos idiomas, el uso de los operadores de cambio en cualquier tipo de datos más pequeño que int cambia automáticamente el tamaño del operando para que sea un int.

Este artículo discutirá los operadores de desplazamiento izquierdo y derecho en C++ y su implementación en detalle, junto con ejemplos relevantes.

Operador de desplazamiento de bits a la izquierda en C++

El operador de desplazamiento a la izquierda desplaza los bits en la expresión de desplazamiento hacia la izquierda el número de lugares en la expresión aditiva. Las posiciones de bits desocupadas por la operación de desplazamiento se rellenan con ceros y los bits desplazados del final se descartan, incluido el bit de signo.

El operador de desplazamiento a la izquierda toma dos números. Esto desplaza los bits del primer operando, y el segundo operando decide el número de lugares a desplazar.

Puedes decir que desplazar a la izquierda un entero a por un entero b, denotado por (a<<b), es equivalente a multiplicar a por 2^b (2 elevado a b). El operador de desplazamiento a la izquierda se indica con <<.

Por ejemplo, M<<k. Aquí, M es el primer operando y k es el segundo operando.

Tomemos M=33; que es 100001 en binario y k = 2. Si M se desplaza a la izquierda por 2, denotado por M=M<<2, se convertirá en M=M(2^2).

Por lo tanto, M=33(2^2)=132 se puede escribir como 10000100.

Ejemplo:

#include <iostream>
using namespace std;

int main() {
  unsigned char x = 6, y = 7;
  cout << "x<<1 = " << (x << 1) << endl;
  cout << "y<<1 = " << (y << 1) << endl;
  return 0;
}

Producción :

x<<1 = 12
y<<1 = 14

En el código anterior, las variables sin signo char x y char y denotan un tipo de datos de carácter en el que la variable usa todos los 8 bits de la memoria, y no hay ningún bit de signo (que está ahí en char con signo).

Aquí, char x es igual a 6, es decir, 00000110 en binario, y char y es igual a 7, es decir, 00000111 en binario.

La primera declaración de impresión indica desplazar a la izquierda el valor de x en 1 bit; el resultado es 00001100. La segunda instrucción de impresión dice desplazar a la izquierda el valor de y en 1 bit; el resultado es 00001110.

Operador de desplazamiento de bits a la derecha en C++

El operador de desplazamiento a la derecha desplaza el patrón de bits en la expresión de desplazamiento por el número de lugares que proporciona la expresión aditiva a la derecha. Las ubicaciones de bits desocupadas por la operación de desplazamiento se rellenan con ceros para valores sin signo.

El bit de signo reemplaza las ubicaciones de bits vacantes en los números con signo. Si el número es positivo, se utiliza el valor 0; si el número es negativo, se utiliza el valor 1.

El operador de turno derecho toma dos números. Esto desplaza los bits del primer operando, y el segundo operando decide el número de lugares a desplazar.

Puedes decir que desplazar a la derecha un entero a por un entero b, denotado como (a>>b), es equivalente a dividir a por 2^b (2 elevado a b). El operador de desplazamiento a la derecha se denota como: >>.

Por ejemplo, M>>k . Aquí, M es el primer operando y k es el segundo.

Tomemos M=32; que es 100000 en binario y k = 2. Si M se desplaza a la derecha en 2, denotado por M=M>>2, entonces M se convertirá en M=M/(2^2). Por lo tanto, M=32/(2^2)=8 se puede escribir como 1000.

Programa de ejemplo:

#include <iostream>

int main() {
  unsigned char x = 6, y = 9;
  cout << "a>>1 = " << (a >> 1) << endl;
  cout << "b>>1 = " << (b >> 1) << endl;
  return 0;
}

Producción :

x>>1 = 3
y>>1 = 4

En el código anterior, la variable sin signo char x y char y denota un tipo de datos de carácter en la variable que usa todos los 8 bits de la memoria, y no hay ningún bit de signo (que está allí en char firmado).

Aquí, char x es igual a 6, es decir, 00000110 en binario, y char y es igual a 9, es decir, 00001001 en binario.

La primera instrucción de impresión indica desplazar a la derecha el valor de x en 1 bit; el resultado es 00000011. La segunda instrucción de impresión establece desplazar a la derecha el valor de y en 1 bit; el resultado es 00000100.

Cambio de bit en el tipo de datos flotante en C++

No puede cambiar de bit un flotante en C++, ya que mostrará un error, pero ¿por qué? Es porque los flotadores se almacenan en un formato especial.

32 bits para un flotante se dividen en dos categorías: un significado y un exponente. Un cambio puede potencialmente cambiar bits de la categoría de exponente a la categoría de significado o viceversa.

Ejemplo:

#include <stdio.h>

int main(int ar, char *arg[]) {
  float testFl = 2.5;

  printf("testFloat (before): %f\n", testFl);
  testFl = testFl << 1;
  printf("testFloat (after): %f\n", testFl);
  return 0;
}

Producción :

error: invalid operands to binary << (have 'float' and 'int')

El desplazamiento a la derecha o el desplazamiento a la izquierda colapsarían todos los bits.

Cambio de bits en Array en C++

Existe un array ar[] de tamaño n y un entero m.

El objetivo es hacer que todos los elementos del array sean > m realizando operaciones de desplazamiento a la derecha en todos los elementos del array presentes. Si no puede hacerlo, imprima -1.

Ejemplo:

Input: ar[] = { 21, 22, 23, 19 }, m = 34
Output: { 26, 26, 27, 25 }

Explanation:
ar[0] = 10101
After 1 right shift, 11010 → 26
ar[1] = 10110
After 3 right shift, 11010 → 26
ar[2] = 10111
After  1 right shift, 11011 → 27
ar[3] = 10011
After 2 right shift, 11001 → 25

Código:

#include <bits/stdc++.h>
using namespace std;

int setBitNumber(int n) {
  int m = log2(n);
  return m;
}

bool check(int ar[], int m, int n) {
  for (int i = 0; i < n; i++) {
    if (ar[i] <= m) return false;
  }
  return true;
}

void modifyArray(int ar[], int m, int n) {
  for (int i = 0; i < n; i++) {
    if (ar[i] > m)
      continue;
    else {
      int bits = setBitNumber(ar[i]);
      int el = ar[i];
      for (int j = 0; j < bits; j++) {
        if (el & 1) {
          el >>= 1;
          el |= (1 << bits);
        } else {
          el >>= 1;
        }
        if (el > m) {
          arr[i] = el;
          break;
        }
      }
    }
  }

  if (check(ar, m, n)) {
    for (int i = 0; i < n; i++) cout << ar[i] << " ";
  } else
    cout << -1;
}

int main() {
  int ar[] = {21, 22, 23, 19};
  int n = sizeof(ar) / sizeof(ar[0]);
  int m = 24;
  modifyArray(ar, m, n);
  return 0;
}

Producción :

[26, 26, 27, 25]

La principal operación realizada en el programa es el recorrido del array. Realiza la operación de desplazamiento a la derecha en cada elemento del arreglo ar[i].

La condición se comprueba si ar[i] > m. Si es cierto, actualice el array ar[i], de lo contrario, continúe.

Si cualquier elemento del array ar[i] ≤ m, entonces imprima -1, de lo contrario imprima el array ar[i].

Desplazamiento de bits y máscara en C++

Una máscara especifica qué bits deben conservarse y cuáles deben borrarse.

Ejemplo:

Mask:   00001111b
Value:  01010101b

Cuando aplicamos la máscara al valor, queremos borrar los primeros cuatro bits (superiores) y mantener los cuatro bits finales (inferiores). Como resultado, hemos recuperado los cuatro bits inferiores.

Producción :

Mask:   00001111b
Value:  01010101b
Result: 00000101b

Los operadores de cambio de bits se utilizan con frecuencia con operaciones de enmascaramiento para quitar bits de un número uno por uno. El siguiente ejemplo explica cómo dividir un carácter sin firmar en una matriz de bits separados.

unsigned char y = 0xD5;
unsigned char bit[8];
unsigned char mask = 1;
for (int x = 7; x >= 0; x--) {
  bits[x] = y & mask;
  y = y >> 1;
}

Cambio de bits para números negativos en C++

Los números negativos no deben ingresarse usando los operadores de desplazamiento hacia la izquierda y hacia la derecha. Si alguno de los operandos es un entero negativo, el resultado es un comportamiento indefinido.

Por ejemplo, el resultado de 1 >> -1 y 1 << -1 no está definido.

#include <iostream>

int main() {
  unsigned char x = -6, cout << "a>>1 = " << (a >> 1) << endl;
  return 0;
}

Producción :

error: undefined behavior in C

Cambio de bits usando Long en C++

El tipo de datos long se utiliza para cambiar los bits en 32 bits o 64 bits.

Ejemplo:

Para 32 bits,

unsigned long A = (1L << 37)

Para 64 bits,

unsigned long long A = (1ULL << 37);

Para implementar lo siguiente usando un programa:

#include <stdio.h>

int main(void) {
  long long y = 1ULL;

  // Left shift 40 times
  y <<= 20;
  y <<= 20;

  printf("y is %lld\n", y);
  return 0;
}

Producción :

y is 1099511627776

Aquí, se toma una variable de 64 bits long long y, y 1ULL es una constante long long int sin signo (64 bits). La variable y se desplaza 40 veces y se imprime.

Conclusión

En este artículo, hemos discutido el operador de cambio de bit en C++. Aprendimos en detalle sobre los operadores de desplazamiento a la izquierda y a la derecha en C++.

Artículo relacionado - C++ Operator