Citant le code pour calculer la valeur absolue entière (abs) sans branchement 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;
Variante brevetée:
r = (v ^ mask) - mask;
Qu'est-ce que c'est CHAR_BIT
et comment l'utiliser?
c
bit-manipulation
dato datuashvili
la source
la source
CHAR_BIT
?" , même si ce n'était pas la question initiale. : (Compte tenu de votre explication, je comprends pourquoi vous avez écrit cette réponse, mais pour la postérité, il pourrait être plus utile soit (a) de supprimer votre réponse et de la réécrire comme un commentaire à la question, afin que @ AraK apparaisse en haut, ou (b) modifiez votre réponse afin qu'elle réponde au titre actuel de la question.CHAR_BIT
est le nombre de bits danschar
. 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.Il peut être trouvé dans
<limits.h>
.la source
CHAR_BIT>=8
et autorise des valeurs beaucoup plus grandes pour les DSP qui n'ont qu'une seule taille de type, souvent 32 bits. POSIX nécessiteCHAR_BIT==8
. En général, vous pouvez supposer que n'importe quelle architecture orientée serveur multi-utilisateur / multitâche ou orientée utilisation interactive avec n'importe quelle chance d'être connecté à Internet ou d'échanger des données textuelles avec le monde extérieurCHAR_BIT==8
.int8_t
etuint8_t
pour exister. Il existe donc un type de largeur 8. Puisquesizeof
tout type doit être compatible avec ensizeof char
faitsizeof int8_t
doit être 1. DoncCHAR_BIT == 8
. J'ai écrit quelque chose autour de cette obéservation ici: gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-bytestdint.h
. Donc là, il est nécessaire, et il est également marqué comme Extension à la norme ISO C , sans faire référence à une version particulière de cette norme. Ma faute.Essayer de répondre à la fois à la question explicite (qu'est-ce que CHAR_BIT) et à la question implicite (comment cela fonctionne-t-il) 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 dans un char. Il doit toujours être au moins égal à 8 en raison d'autres exigences du type char. En pratique, sur tous les ordinateurs à usage général modernes, 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 de sizeof, il n'est pas nécessaire car tous les types primitifs en Java sont de taille fixe et la structure interne des objets 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 une extension sur les décalages de bits des nombres signés et en supposant que votre système utilise une représentation complémentaire de 2s pour les nombres négatifs, cela signifie que "MASK" sera 0 pour une valeur positive ou zéro et -1 pour une valeur négative.
Pour annuler un nombre de complément à deux, nous devons effectuer un non au niveau du bit, puis en ajouter un. De manière équivoque, nous pouvons en soustraire un, puis le nier au niveau du bit.
Encore une fois, en supposant que la représentation du complément à deux - -1 est représentée par tous les uns, donc exclusif ou avec -1 équivaut à une négation au niveau du bit.
Ainsi, lorsque v vaut zéro, le nombre est laissé seul, lorsque v est égal à un, il est annulé.
Il faut savoir que le débordement signé en C et C ++ est un comportement indéfini. Donc, utiliser cette implémentation ABS sur la valeur la plus négative conduit à un comportement indéfini. Cela peut être résolu en ajoutant des transtypages de sorte que la dernière ligne du programme soit évaluée dans unsigned int.
* 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 adresser. Une mise en œuvre peut potentiellement combiner plusieurs unités de mémoire adressable par matériel en 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 adressable par programme.
la source