web-dev-qa-db-fra.com

Quel est le but de "int mask = ~ 0;"?

J'ai vu la ligne de code suivante ici en C.

 int mask = ~0;

J'ai imprimé la valeur de mask en C et C++. Il imprime toujours -1.

J'ai donc quelques questions:

  • Pourquoi attribuer une valeur ~0 à la variable du masque ?
  • Quel est le but de ~0?
  • Pouvons-nous utiliser -1 au lieu de ~0?
44
Jayesh

C'est une façon portable de définir tous les bits binaires d'un entier sur 1 bit sans avoir à savoir combien de bits sont dans l'entier sur l'architecture actuelle.

79
Richard Hodges

C et C++ autorisent 3 formats entiers signés différents: amplitude du signe, complément à un et complément à deux

~0 produira des bits tout-en-un quel que soit le format de signe que le système utilise. C'est donc plus portable que -1

Vous pouvez ajouter le suffixe U (c'est-à-dire -1U) pour générer un modèle de bits tout-en-un portable1. Toutefois ~0 indique l'intention plus claire : inverser tous les bits dans la valeur 0 alors que -1 montrera qu'une valeur de moins un est nécessaire, pas son binaire représentation

1 parce que les opérations non signées sont toujours modulo réduit le nombre qui est un supérieur à la plus grande valeur qui peut être représentée par le type résultant

36
phuclv

Que sur une plate-forme complémentaire de 2 (c'est supposé) vous donne -1, mais écrire -1 directement est interdit par les règles (seulement les entiers 0..255, unaire !, ~ et binaire &, ^, |, +, << et >> sont autorisés).

8
6502

Vous étudiez un défi de codage avec un certain nombre de restrictions sur les opérateurs et les constructions de langage pour effectuer des tâches données.

Le premier problème est retourne la valeur -1 sans utiliser le - opérateur.

Sur les machines qui représentent des nombres négatifs avec un complément à deux, la valeur -1 est représenté avec tous les bits définis sur 1, alors ~0 correspond à -1:

/* 
 * minusOne - return a value of -1 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 2
 *   Rating: 1
 */
int minusOne(void) {
  // ~0 = 111...111 = -1
  return ~0;
}

D'autres problèmes dans le fichier ne sont pas toujours implémentés correctement. Le deuxième problème, renvoyer une valeur booléenne représentant le fait qu'une valeur int rentrerait dans un _ 16 $ signé short a un défaut:

/* 
 * fitsShort - return 1 if x can be represented as a 
 *   16-bit, two's complement integer.
 *   Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 1
 */
int fitsShort(int x) {
  /* 
   * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
   * so after shift, if x remains the same, then it means that x can be represent as 16-bit
  */
  return !(((x << 16) >> 16) ^ x); 
}

Le décalage vers la gauche d'une valeur négative ou d'un nombre dont la valeur décalée dépasse la plage de int a un comportement indéfini, le décalage vers la droite d'une valeur négative est défini par l'implémentation, de sorte que la solution ci-dessus est incorrecte (bien que ce soit probablement la solution attendue) .

5
chqrlie

Il y a longtemps, c'est ainsi que vous avez économisé de la mémoire sur des équipements extrêmement limités tels que l'ordinateur 1K ZX 80 ou ZX 81. En BASIC, vous

Let X = NOT PI

plutôt que

LET X = 0

Étant donné que les nombres étaient stockés sous forme de virgules flottantes de 4 octets, ce dernier prend 2 octets de plus que la première alternative NOT PI, où chacun de NOT et PI prend un seul octet.

2
skaak

Il existe plusieurs façons de coder les nombres dans toutes les architectures informatiques. Lorsque vous utilisez le complément de 2, cela sera toujours vrai: ~0 == -1. D'un autre côté, certains ordinateurs utilisent le complément de 1 pour coder les nombres négatifs pour lesquels l'exemple ci-dessus est faux, car ~0 == -0. Oui, le complément 1 a un zéro négatif, et c'est pourquoi il n'est pas très intuitif.

Donc à vos questions

  • le ~ 0 est assigné au masque donc tous les bits du masque sont égaux 1 -> faisant mask & sth == sth
  • le ~ 0 est utilisé pour rendre tous les bits égaux à 1 quelle que soit la plate-forme utilisée
  • vous pouvez utiliser -1 au lieu de ~ 0 si vous êtes sûr que votre plate-forme informatique utilise l'encodage du complément numéro 2

Ma pensée personnelle - rendez votre code aussi indépendant de la plateforme que possible. Le coût est relativement faible et le code devient infaillible

0
bartop