Représentation des nombres négatifs en C?

Comment C représente-t-il des entiers négatifs?

Est-ce par la représentation du complément à deux ou en utilisant le bit le plus significatif (MSB)?

-1 en hexadécimal est ffffffff .

Alors s’il vous plaît clarifiez cela pour moi.

La section 6.2.6.2/2 ISO C (C99) stipule qu’une implémentation doit choisir l’une des trois représentations différentes pour les types de données intégrales, complément à deux, complément à un ou signe / grandeur (bien qu’il soit extrêmement probable que l’implémentation de complément à deux l’emportent sur les autres).

Dans toutes ces représentations, les nombres positifs sont identiques, la seule différence étant les nombres négatifs.

Pour obtenir la représentation négative d’un nombre positif, vous:

  • inverser tous les bits, puis append un complément à deux.
  • inverser tous les bits pour le complément des uns.
  • inverser uniquement le bit de signe pour le signe / magnitude.

Vous pouvez le voir dans le tableau ci-dessous:

 nombre |  complément de deux |  les compléments |  signe / grandeur
 ======= | ===================== | =================== = | =====================
      5 |  0000 0000 0000 0101 |  0000 0000 0000 0101 |  0000 0000 0000 0101
     -5 |  1111 1111 1111 1011 |  1111 1111 1111 1010 |  1000 0000 0000 0101

Gardez à l’esprit que l’ISO n’impose pas que tous les bits soient utilisés dans la représentation. Ils introduisent le concept d’un bit de signe, de bits de valeur et de bits de remplissage. Maintenant, je n’ai jamais réellement vu d’implémentation avec des bits de remplissage, mais, d’après le document de justification C99, ils ont cette explication:

Supposons qu’une machine utilise une paire de courts-circuits de 16 bits (chacun avec son propre bit de signe) pour constituer un int de 32 bits et que le bit de signe du plus bas court est ignoré lorsqu’il est utilisé dans cet int de 32 bits. Ensuite, en tant qu’int signé 32 bits, il existe un bit de remplissage (au milieu des 32 bits) qui est ignoré lors de la détermination de la valeur de l’int signé 32 bits. Toutefois, si cet élément 32 bits est traité comme un entier non signé 32 bits, alors ce bit de remplissage est visible par le programme de l’utilisateur. On a dit au comité C qu’il existe une machine qui fonctionne de cette façon, et c’est l’une des raisons pour lesquelles des bits de remplissage ont été ajoutés à C99.

Je crois que cette machine à laquelle ils faisaient allusion était le Datacraft 6024 (et ses successeurs de Harris Corp). Dans ces machines, un mot de 24 bits était utilisé pour l’entier signé, mais si vous vouliez un type plus large, il en enchaînait deux en une valeur de 47 bits avec le bit de signe de l’un des mots ignoré:

 +---------+-----------+--------+-----------+ | sign(1) | value(23) | pad(1) | value(23) | +---------+-----------+--------+-----------+ \____________________/ \___________________/ upper word lower word 

C permet le signe / magnitude, le complément à un et le complément à deux des entiers signés. Le matériel le plus typique utilise le complément à deux pour les entiers et le signe / magnitude pour la virgule flottante (et une autre possibilité – une représentation “biaisée” de l’exposant en virgule flottante).

-1 en hexadécimal est ffffffff. Alors s’il vous plaît clarifiez-moi à cet égard.

Dans le complément à deux (de loin la représentation la plus couramment utilisée), chaque bit, à l’exception du bit le plus significatif (MSB), de droite à gauche (ordre de grandeur croissant) a la valeur 2 n,n augmente de zéro de un. Le MSB a la valeur -2 n .

Ainsi, par exemple, dans un entier de 8 bits à deux-complément, le MSB a la valeur de position -2 7 (-128), de sorte que le nombre binary: 1111 1111 2 est égal à -128 + 0111 1111 2 = -128 + 127 = -1

Une caractéristique utile du complément à deux est que l’UAL d’un processeur nécessite uniquement un bloc additionneur pour effectuer la soustraction, en formant le complément à deux de l’opérande de la main droite. Par exemple, 10 – 6 équivaut à 10 + (-6); en binary 8 bits (pour simplifier l’explication), cela ressemble à:

  0000 1010 +1111 1010 --------- [1]0000 0100 = 4 (decimal) 

Où [1] est le bit de report rejeté. Un autre exemple; 10 – 11 == 10 + (-11):

  0000 1010 +1111 0101 --------- 1111 1111 = -1 (decimal) 

Une autre caractéristique du complément à deux est qu’il a une valeur unique représentant zéro, alors que l’amplitude du signe et son complément ont chacun deux; +0 et -0.

Pour les types intégraux, il s’agit généralement d’un complément à deux (spécifique à l’implémentation). Pour une virgule flottante, il y a un bit de signe.