Comparer les bits en C

Jinku Hu 12 octobre 2023
Comparer les bits en C

Cet article explique plusieurs méthodes de comparaison des bits en C.

Implémenter une fonction personnalisée à l’aide d’opérations XOR et AND au niveau du bit pour la comparaison de bits en C

Généralement, la comparaison de bits implique d’accéder à des valeurs de bit unique et d’effectuer les opérations nécessaires, telles que l’implémentation d’un champ de bits en utilisant les mots-clés union et struct. Cependant, les opérations au niveau du bit offrent une méthode plus efficace pour comparer les bits spécifiés en nombres. Dans ce cas, nous implémentons une fonction distincte adaptée au type u_int32_t, dont la largeur est garantie de 32 bits.

L’exemple de programme prend trois entiers comme arguments de ligne de commande, dont les deux premiers sont les nombres comparés, tandis que le troisième entier spécifie le n-ième bit. Notez que nous convertissons les éléments argv en utilisant strtol, perdant ainsi un peu de précision lors du stockage des valeurs de retour dans le type u_int32_t. La fonction compareBits déclare deux variables locales stockant des valeurs intermédiaires - mask et tmp. Nous positionnons le n-ième bit dans le masque en décalant le 1 vers la gauche de nième - 1 positions. Ensuite, les deux numéros d’entrée utilisateur sont XOR-ed pour obtenir les différences de bits dans chaque position avec un bit défini dans le résultat indiquant des valeurs différentes. Enfin, nous devons extraire le bit de la n-ième position et vérifier si la valeur est 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);
}

exemple de format de fichier:

./program 1234 1231 1

Format de fichier d’entrée:

bits not equal!

A titre d’exemple, les entiers 1234 et 1231 sont représentés en binaire par 00000000000000000000010011010010 et 00000000000000000000010011001111, respectivement. Ainsi, XOR-ing ces deux aboutit à une représentation binaire 00000000000000000000000000011101, qui est finalement AND-ed avec le masque 00000000000000000000000000000010 pour extraire la valeur de position de bit unique. Si le résultat est tous zéros, cela implique que les bits comparés sont égaux; sinon, c’est le contraire.

Cependant, nous pouvons également raccourcir la fonction compareBits et déplacer les opérations XOR/AND vers l’instruction return comme indiqué dans l’exemple de code suivant. Notez que la fonction renvoie l’opposé logique des opérations XOR/AND au niveau du bit, car nous sortons les messages correspondants dans la fonction appelante en utilisant le ? : Déclaration tenaire.

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

exemple de format de fichier:

./program 1234 1231 2

Format de fichier d’entrée:

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