Forum Clubic

[Résolu][C++] La révolte des macros

Bonjour,

Je me suis remis gentillement à la progue ces derniers temps mais j’ai un petit problème. Voici un macro qui permet d’isoler un bit dans un byte

#define SEP_BYTE(byte, n) ((byte << (7-n)) >> 7)

Il faudrait donc que ce macro me donne une valeur à 0 ou à 1 (suivant la position du bit). Oui mais voilà le bug!

Quand j’execute un code comme ça :


unsigned char entry = 7;
unsigned char ret = SEPS_BYTE(entry, 1);

la valeur “ret” contient un 3 ! C’est comme si le compilateur simplifiait le macro en faisant la différence entre les deux décalages dans le sens opposés afin d’en faire qu’un. Mais ça fausse totalement le résultat !!

Voyez-vous l’erreur que j’ai commise?

Merci d’avance

Note : J’ai testé avec une fonction qui exécute un décalage dans un sens puis dans l’autre sens (sur des lignes différentes) et ça marche!

Déjà, utilise CHAR_BIT et pas 7. Sauf si tu veux vraiment que tes char tiennent que sur 8 bits. CHAR_BIT se trouve dans limits.h normalemnt et vaut 8 (= nombre de bit dans un char)

D’où:

#define SEP_BYTE(byte, n) ((byte << ((CHAR_BIT-1)-n)) >> (CHAR_BIT-1))

Ca c’est pour la correction.

Pour le reste, peux tu essayer comme ça :

unsigned char entry = 7U;
unsigned char ret = SEP_BYTE(entry, 1);

Parce qu’en fait, si ton char est vu avec un bit de signe, le décallage à droite ne va pas trop aider. Ceci dit entry est unsigned char. (au passage: c’est SEP_BYTE, pas SEPS_BYTE)

Pour le reste, je ne vois pas.

Essaye un gcc/g++ avec l’option -E pour voir comment est transformé ta macro.

(au passage, si tu veux retourner 0 ou 1, je pense que c’est avec un masque qu’il faudrait le faire)


#define SEP_BYTE(byte, n) ( (byte >> (n-1)) & ((1 << 1)-1) )

Il faut décaler ET isoler le bit.

Bien ce que je disais :slight_smile: il manque un masque.

Merci beaucoup,

mais j’ai quand même deux petites questions que j’arrive pas à enlever de mon cerveau nevrosé.

1. Tu me proposes ce macro qui marche très bien mais pourquoi avoir écrit ceci

#define SEP_BYTE(byte, n) ( (byte >> (n-1)) & ((1 << 1)-1) )

et pourquoi pas ceci ?!?!?!

#define SEPS_BYTE(byte, n) ( (byte >> n) & 1 )

2. Je sais que je suis obstiné mais je ne comprends toujours pas l’erreur que j’ai commise, j’aimerais bien comprendre pour pas la reproduire plus tard :sweet: .

  1. comme je te l’ai dis, si tu veux vérifier la valeur d’un bit, savoir s’il est on ou off, c’est quasi exclusivement par un &.

L’idée étant de construire un masque ne contenant un bit activé correspondant au bit dont tu veux savoir s’il est on ou off:

en gros (0b00001101 & 0b00001000) >> 3 -> 1 ou 0

J’ai bidouillé ma macro qui ne fonctionne pas comme la tienne car je prend le n bit de n longeur


#define SEP_BYTE(byte, bit, bit_len) ( (byte >> (bit-1)) & ((1 << bit_len)-1) )

Ton erreur vient du fait que tu ne fait que des décalage, tu n’isoles aucun bit, la tu travaille sur le mot, c’est plus comme si tu voulais modifier le bit que si tu voulais l’isoler.
Je te conseille de googler sur les masques de bits histoire que tu comprennes l’arithmetique binaire.

Ha… OK merci à tous. Vous m’avez vraiment aidé. Je vais un peu googler comme tu dis :slight_smile: