Qu’est ce que c’est CHAR_BIT?

Citant le code pour calculer la valeur absolue entière (abs) sans twigment à partir de http://graphics.stanford.edu/~seander/bithacks.html :

int v; // we want to find the absolute value of v unsigned int r; // the result goes here int const mask = v >> sizeof(int) * CHAR_BIT - 1; r = (v + mask) ^ mask; 

Variation brevetée:

 r = (v ^ mask) - mask; 

Qu’est-ce que CHAR_BIT et comment l’utiliser?

Vous devez savoir que ce code dépend du comportement, défini par l’implémentation, des bitshift corrects sur les types signés. gcc promet de toujours donner le comportement sain (extension du bit de signe) mais ISO C permet à l’implémentation de remplir les bits supérieurs par zéro.

Une solution à ce problème:

 #ifdef HAVE_SIGN_EXTENDING_BITSHIFT int const mask = v >> sizeof(int) * CHAR_BIT - 1; #else int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1); #endif 

Votre Makefile ou config.h etc. peut définir HAVE_SIGN_EXTENDING_BITSHIFT au moment de la construction en fonction de votre plate-forme.

CHAR_BIT est le nombre de bits dans char . De nos jours, presque toutes les architectures utilisent 8 bits par octet mais ce n’est pas toujours le cas. Certaines machines plus anciennes avaient un octet de 7 bits.

On peut le trouver dans

Essayer de répondre à la fois à la question explicite (qu’est-ce que CHAR_BIT) et à la question implicite (comment ça marche) dans la question d’origine.


Un caractère en C et C ++ représente la plus petite unité de mémoire que le programme C peut adresser *

CHAR_BIT en C et C ++ représente le nombre de bits d’un caractère. Il doit toujours être au moins 8 en raison d’autres exigences sur le type de caractère. En pratique, sur tous les ordinateurs modernes à usage général, il s’agit exactement de 8, mais certains systèmes historiques ou spécialisés peuvent avoir des valeurs plus élevées.

Java n’a pas d’équivalent de CHAR_BIT ou sizeof, il n’y a pas besoin car tous les types primitifs de Java sont de taille fixe et la structure interne des objects est opaque pour le programmeur. Si vous traduisez ce code en Java, vous pouvez simplement remplacer “sizeof (int) * CHAR_BIT – 1” par la valeur fixe 31.

Dans ce code particulier, il est utilisé pour calculer le nombre de bits dans un int. Sachez que ce calcul suppose que le type int ne contient aucun bit de remplissage.

En supposant que votre compilateur choisisse de signer des décalages de nombres signés et en supposant que votre système utilise une représentation de complément à 2 pour les nombres négatifs, cela signifie que “MASK” sera 0 pour une valeur positive ou nulle et -1 pour une valeur négative.

Pour annuler un nombre à deux complément, nous devons effectuer un pas au niveau du bit et en append un. De manière équivoque, nous pouvons soustraire un puis le neutraliser au niveau du bit.

Encore une fois, en supposant que la représentation du complément à deux est représentée par toutes les parties, une exclusivité ou une valeur -1 équivaut à une négation au niveau du bit.

Donc, quand v vaut zéro, le nombre est laissé seul, quand v est un, il est annulé.

Quelque chose à savoir, c’est que le débordement signé en C et C ++ est un comportement indéfini. L’utilisation de cette implémentation d’ABS sur la valeur la plus négative conduit donc à un comportement indéfini. Cela peut être corrigé en ajoutant des moulages tels que la dernière ligne du programme soit évaluée dans unsigned int.

* Ce qui est généralement mais pas la même chose que la plus petite unité de mémoire que le matériel peut traiter. Une implémentation peut potentiellement combiner plusieurs unités de mémoire adressable par matériel dans une unité de mémoire adressable par programme ou diviser une unité de mémoire adressable par matériel en plusieurs unités de mémoire programmable.