Usar operaciones de desplazamiento bit a bit en C

Jinku Hu 12 octubre 2023
  1. Utilice el operador << para desplazar el número hacia la izquierda en C
  2. Use Shift a la izquierda para múltiples enteros por dos en C
  3. Cambio a la derecha: diferencia aritmética vs cambio lógico en C
Usar operaciones de desplazamiento bit a bit en C

Este artículo explicará varios métodos de cómo utilizar operaciones de desplazamiento bit a bit en C.

Utilice el operador << para desplazar el número hacia la izquierda en C

Las operaciones de desplazamiento bit a bit son parte de todos los lenguajes de programación y reposicionan cada bit de un operando entero por el número especificado de lugares. Para demostrar mejor los efectos de estas operaciones, incluimos la función denominada binary en los siguientes ejemplos que imprime la representación binaria para el entero dado. Tenga en cuenta que esta función solo está implementada para trabajar con valores enteros de 32 bits. El siguiente código de ejemplo demuestra el desplazamiento a la izquierda en dos posiciones y muestra las representaciones numéricas en consecuencia.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n1 = 123;

  binary(n1);
  printf(" : %d\n", n1);
  n1 <<= 2;
  binary(n1);
  printf(" : %d\n", n1);

  exit(EXIT_SUCCESS);
}

Producción :

00000000000000000000000001111011 : 123
00000000000000000000000111101100 : 492

Use Shift a la izquierda para múltiples enteros por dos en C

Podemos utilizar la operación de desplazamiento a la izquierda para implementar la multiplicación por dos, lo que puede ser más eficiente en el hardware. Tenga en cuenta que cuando se desplaza a la izquierda, no hay diferencia entre el desplazamiento aritmético y lógico. El cambio de posición única para el entero dado da como resultado una multiplicación; por lo tanto, podemos cambiar más para obtener la multiplicación en consecuencia.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n1 = 123;

  printf("%d\n", n1);
  n1 <<= 1;
  printf("%d x2\n", n1);

  exit(EXIT_SUCCESS);
}

Producción :

492
984 x2

Cambio a la derecha: diferencia aritmética vs cambio lógico en C

Cabe mencionar que los enteros con signo y sin signo se representan de forma diferente debajo del capó. Es decir, los con signo se implementan como valores de complemento a dos. Como resultado, el bit más significativo de números negativos es 1 llamado bit de signo, mientras que los enteros positivos comienzan con 0 como de costumbre. Por lo tanto, cuando desplazamos los números negativos a la derecha lógicamente, perdemos su signo y obtenemos el entero positivo. Entonces, necesitamos diferenciar los cambios lógicos y aritméticos, el último de los cuales conserva el bit más significativo. Aunque hay diferencias entre los conceptos, C no proporciona operadores separados. Además, el estándar C no especifica el comportamiento, ya que está definido por la implementación del hardware. Como se muestra en el siguiente ejemplo de salida, la máquina subyacente realizó el cambio aritmético y conservó el valor negativo del entero.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n2 = -24;

  binary(n2);
  printf(" : %d\n", n2);
  n2 >>= 3;
  binary(n2);
  printf(" : %d\n", n2);

  exit(EXIT_SUCCESS);
}

Producción :

11111111111111111111111111101000 : -24
11111111111111111111111111111101 : -3
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook