Comparar bits en C

Jinku Hu 12 octubre 2023
Comparar bits en C

Este artículo explicará varios métodos de cómo comparar bits en C.

Implementar una función personalizada usando operaciones XOR y AND a nivel de bits para la comparación de bits en C

Generalmente, la comparación de bits implica acceder a valores de un solo bit y realizar las operaciones necesarias, como implementar un campo de bits utilizando palabras clave union y struct. Sin embargo, las operaciones bit a bit ofrecen un método más eficiente para comparar bits especificados en números. En este caso, implementamos una función separada adecuada para el tipo u_int32_t, que está garantizado para tener un ancho de 32 bits.

El programa de ejemplo toma tres enteros como argumentos de la línea de comandos, los dos primeros son los números que se comparan, mientras que el tercer entero especifica el n-ésimo bit. Observe que convertimos elementos argv usando strtol, perdiendo así algo de precisión al almacenar los valores devueltos en el tipo u_int32_t. La función compareBits declara dos variables locales que almacenan valores intermedios: mask y tmp. Establecemos el n-ésimo bit en la mask desplazando el 1 a la izquierda por las posiciones nth - 1. Luego, ambos números de entrada de usuario son XOR-ed para obtener las diferencias de bits en cada posición con un bit establecido en el resultado que denota valores diferentes. Finalmente, necesitamos extraer el bit de la n-ésima posición y verificar si el valor es 0.

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

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask, tmp;

  mask = 1 << (nth - 1);
  tmp = n1 ^ n2;

  if ((tmp & mask) == 0)
    return true;
  else
    return false;
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

formato de archivo de muestra:

./program 1234 1231 1

Formato de archivo de entrada:

bits not equal!

Como ejemplo, los números enteros 1234 y 1231 se representan en binario como 00000000000000000000010011010010 y 00000000000000000000010011001111, respectivamente. Por lo tanto, XOR-ing estos dos dan como resultado una representación binaria 00000000000000000000000000011101, que finalmente se realiza en AND con la máscara 00000000000000000000000000000010 para extraer el valor de posición de un solo bit. Si el resultado es todo ceros, implica que los bits comparados son iguales; de lo contrario, es lo contrario.

Alternativamente, sin embargo, podemos acortar la función compareBits y mover las operaciones XOR/AND a la declaración return como se muestra en el siguiente código de ejemplo. Tenga en cuenta que la función devuelve el opuesto lógico de las operaciones XOR/AND bit a bit, ya que generamos los mensajes correspondientes en la función de llamada utilizando el ? : Declaración de tenario.

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

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask;

  mask = 1 << (nth - 1);

  return !((n1 ^ n2) & mask);
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

formato de archivo de muestra:

./program 1234 1231 2

Formato de archivo de entrada:

bits equal!
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