Comparar bits em C

Jinku Hu 12 outubro 2023
Comparar bits em C

Este artigo irá explicar vários métodos de como comparar bits em C.

Implementar uma função personalizada usando operações Bitwise XOR e AND para comparação de bits em C

Geralmente, a comparação de bits envolve acessar valores de bit único e realizar as operações necessárias, como implementar campo de bits usando palavras-chave union e struct. Embora as operações bit a bit ofereçam um método mais eficiente de comparação de bits especificados em números. Nesse caso, implementamos uma função separada adequada para o tipo u_int32_t, que tem a garantia de largura de 32 bits.

O programa de exemplo leva três inteiros como argumentos de linha de comando, os dois primeiros dos quais são os números que são comparados, enquanto o terceiro inteiro especifica o n-ésimo bit. Observe que convertemos elementos argv usando strtol, perdendo assim alguma precisão ao armazenar os valores de retorno no tipo u_int32_t. A função compareBits declara duas variáveis locais que armazenam valores intermediários - mask e tmp. Definimos o n-ésimo bit na mask deslocando o 1 para a esquerda por n-ésimo - 1 posições. Então, ambos os números de entrada do usuário são XOR-ed para obter as diferenças de bit em cada posição com um bit definido no resultado denotando valores diferentes. Finalmente, precisamos extrair o bit da enésima posição e verificar se o valor é 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);
}

exemplo de formato de arquivo:

./program 1234 1231 1

Formato de arquivo de entrada:

bits not equal!

Como exemplo, os inteiros 1234 e 1231 são representados em binário como 00000000000000000000010011010010 e 00000000000000000000010011001111, respetivamente. Assim, fazer o XOR desses dois resultar na representação binária 00000000000000000000000000011101, que é finalmente AND com a máscara 00000000000000000000000000000010 para extrair o valor da posição do bit único. Se o resultado for zeros, isso implica que os bits comparados são iguais; caso contrário, é o oposto.

Como alternativa, porém, podemos encurtar a função compareBits e mover as operações XOR/AND para a instrução return conforme mostrado no código de exemplo a seguir. Observe que a função retorna o oposto lógico das operações XOR/AND bit a bit, conforme geramos as mensagens correspondentes na função do chamador usando o ? : declaração provisória.

#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);
}

exemplo de formato de arquivo:

./program 1234 1231 2

Formato de arquivo 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