web-dev-qa-db-fra.com

Qu'est-ce que CHAR_BIT?

Citant le code pour calculer la valeur absolue entière (abs) sans dériver 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;

Quel est CHAR_BIT et comment l'utiliser?

83
dato datuashvili

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

Une façon de contourner 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.

1
R..

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 7 bits.

Il peut être trouvé dans <limits.h>.

204
AraK

Essayer de répondre à la fois à la question explicite (qu'est-ce que CHAR_BIT) et à la question implicite (comment cela fonctionne-t-elle) 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 traiter *

CHAR_BIT en C et C++ représente le nombre de bits dans 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 est 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'est pas nécessaire car tous les types primitifs de Java sont de taille fixe et la structure interne des objets est opaque pour le programmeur. Si la traduction de 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 choisit de signer l'extension sur les décalages binaires des nombres signés et en supposant que votre système utilise une représentation complémentaire de 2 pour les nombres négatifs, cela signifie que "MASQUE" sera 0 pour une valeur positive ou nulle et -1 pour une valeur négative.

Pour annuler un nombre de complément à deux, nous devons effectuer un pas au niveau du bit, puis en ajouter un. De manière équivalente, nous pouvons soustraire un, puis le supprimer au niveau du bit.

En supposant à nouveau que la représentation du complément à deux -1 est représentée par tous, donc exclusive ou avec -1 équivaut à la négation au niveau du bit.

Ainsi, lorsque v est nul, le nombre est laissé seul, lorsque v est un, il est annulé.

Il faut savoir que le débordement signé en C et C++ est un comportement non défini. Ainsi, l'utilisation de cette implémentation ABS sur la valeur la plus négative conduit à un comportement indéfini. Cela peut être corrigé en ajoutant des transtypages de telle sorte que la dernière ligne du programme soit évaluée en entier non signé.

* Ce qui est généralement, mais pas nécessairement, la même que la plus petite unité de mémoire que le matériel peut traiter. Une mise en œuvre peut potentiellement combiner plusieurs unités de mémoire adressable par le matériel en une unité de mémoire adressable par programme ou diviser une unité de mémoire adressable par le matériel en plusieurs unités de mémoire adressable par programme.

2
plugwash