5.3 Représentation de l'information au niveau machine
Objectifs d'apprentissage
À la fin de cette section, vous serez capable de :
- Interpréter les nombres binaires
- Expliquer l'utilisation des codes de caractères standard pour représenter les lettres et les symboles
- Définir les nombres binaires fractionnaires et expliquer comment ils sont utilisés
Dans cette section, nous examinons deux types d'informations très importants et largement utilisés : les nombres et le texte. La raison pour laquelle nous nous concentrons sur ces deux types est qu'ils sont standardisés, et que presque tous les ordinateurs les stockent dans le même format, contrairement à d'autres types d'informations qui ont de nombreux formats différents, dont certains sont propriétaires.
Il est important de savoir qu'une série de bits n'a pas de signification en soi. Par exemple, pour interpréter ou traduire le nombre binaire 0011 comme un nombre décimal, vous devez savoir s'il s'agit d'un entier non signé ou d'un entier signé (signed integer). Par conséquent, nous devons comprendre comment les différents types d'informations sont présentés en binaire.
Représentation des nombres entiers
En tant qu'êtres humains, nous pensons toujours en nombres, spécifiquement en décimales. Chaque fois que vous mentionnez un nombre, il est généralement sous forme décimale ; c'est-à-dire en base 10. Mais que signifie « base 10 » ? Cela signifie que la valeur du nombre est calculée en le parcourant de droite à gauche. Et à chaque chiffre, vous le multipliez par 10 à la puissance de la position de ce chiffre. Le chiffre le plus à droite, appelé chiffre le moins significatif, a la position 0. Le suivant est à la position 1, et ainsi de suite. La Figure 5.11(a) illustre ce processus.
Qu'en est-il des nombres binaires ? Les nombres binaires utilisent la base 2 et sont présentés comme une série de 1 et de 0. Pour passer du binaire à l'équivalent décimal, nous devons différencier la manière dont les entiers non signés et les entiers signés sont représentés en binaire.
Lien interactif
La meilleure façon d'avoir une vue claire de la manière dont les nombres sont traduits en binaire afin que les ordinateurs puissent les traiter est de voir le processus en action. Visitez ce site pour convertir n'importe quel nombre du décimal au binaire et vice versa et pour en savoir plus sur la façon de le faire manuellement.
Représentation des nombres entiers non signés
Un entier non signé (unsigned integer) est un entier non négatif qui commence à partir de 0. Si vous voyez un nombre en binaire et qu'on vous dit que ce nombre représente un nombre non signé, vous pouvez obtenir son équivalent décimal de la même manière que les entiers en base 10, mais en utilisant la base 2 à la place. La Figure 5.11(b) montre l'opération d'obtention de l'équivalent décimal du nombre binaire 101 en partant de la droite et en se déplaçant vers la gauche. Le bit le moins significatif a la position 0, le suivant a la position 1, et ainsi de suite. À chaque élément que vous rencontrez, ajoutez X × 2p, où p est la position du chiffre et X est le chiffre lui-même (0 ou 1), à la somme totale.
Une chose importante à garder à l'esprit est la plage de nombres qui peut être présentée par un nombre non signé. Un bit peut présenter seulement deux valeurs : 1 et 0. Deux bits peuvent présenter quatre valeurs : 00, 01, 10 et 11, qui correspondent à 0, 1, 2 et 3. Trois bits peuvent présenter huit valeurs. En général, n bits peuvent présenter 2n valeurs, ce qui correspond à la plage de 0 à 2n – 1. Comme vous pouvez le constater, il n'y a pas de nombres négatifs. Pour pouvoir présenter des nombres négatifs, nous devons utiliser des nombres signés.
Représentation des nombres entiers signés
Un entier signé (signed integer) est un entier qui peut être négatif ou positif. Le mot signé signifie qu'il possède un signe + ou –. Pour présenter les nombres négatifs, les concepteurs ont expérimenté plusieurs options avant de choisir l'option de facto. L'option évidente est d'utiliser le bit le plus significatif (c'est-à-dire le bit le plus à gauche) comme bit de signe, où 0 signifie positif et 1 signifie négatif. Le reste du nombre est traité avec une méthode appelée signe-magnitude. Est-ce une bonne option ? Regardons la première colonne de la Figure 5.12. Elle représente le signe-magnitude pour un nombre de 3 bits. Nous constatons deux choses.
Premièrement, il y a deux représentations de 0 (+0 et –0), ce qui est un gaspillage de données. Deuxièmement, les nombres ne sont pas symétriques autour de 0. C'est-à-dire que, habituellement, le nombre après 0 est +1 et celui avant 0 est –1. Ce n'est pas le cas ici. L'importance de cette symétrie est de simplifier un peu le matériel.
La deuxième méthode à essayer est un peu moins intuitive. Elle est appelée la méthode du complément à un (one’s complement) d'un nombre binaire, qui est obtenue en inversant chaque 1 du nombre original en 0 et chaque 0 en 1. Par exemple, le complément à un de 101 est 010. La méthode du complément à un est expliquée plus en détail :
- Vérifiez le bit le plus significatif et s'il est à 1, le nombre est négatif et est représenté sous sa forme de complément à un. Pour obtenir le nombre original, vous devez obtenir son complément à un.
- Le complément à un du complément à un est le nombre original. Par exemple, le complément à un de 101 est 010. Le complément à un de 010 est 101.
- En regardant la deuxième colonne de la Figure 5.12, prenons un nombre tel que 110. Son bit le plus significatif est 1, donc le nombre est négatif et sous sa forme de complément à un. Pour connaître sa valeur originale, nous devons obtenir à nouveau son complément à un. Le complément à un de 110 est 001, ce qui correspond au nombre décimal 1, donc le résultat est –1.
- Si le bit le plus significatif est 0, alors le nombre est positif, et pour obtenir son équivalent décimal, nous le traitons comme s'il était non signé. Avec le nombre 010, le bit le plus significatif est 0, donc le nombre est positif et l'équivalent décimal de 010 est 2. Par conséquent, le résultat est +2.
Le complément à un est-il une bonne méthode ? Il y a un effet de symétrie autour de +3/–3. Mais nous avons toujours les deux représentations de 0. La troisième méthode est appelée le complément à deux, qui est la méthode la moins intuitive. Il est important de noter que ce qui est bon pour les machines n'est pas intuitif ou facile pour les êtres humains !
Le complément à deux (two’s complement) d'un nombre binaire est simplement le complément à un auquel on ajoute 1. Par exemple, pour obtenir le complément à un de 011, nous le faisons en deux étapes. Premièrement, nous obtenons le complément à un : 011 est 100. Deuxièmement, nous ajoutons 1 au résultat : 100 + 1 = 101, et 101 est le complément à deux de 011. Maintenant que nous connaissons la définition du complément à deux, voyons comment nous pouvons obtenir l'équivalent décimal d'un nombre binaire. Nous appliquons une technique très similaire à celle du complément à un, mais en utilisant le complément à deux.
Regardez le bit le plus significatif. S'il est 0, le nombre est positif, et l'équivalent décimal peut être calculé comme si le nombre était non signé. Par exemple, 011 est positif et l'équivalent décimal est +3. Si le bit le plus significatif est 1, alors le nombre est négatif, et il est écrit sous sa forme de complément à deux. De plus, le complément à deux du complément à deux ramène le nombre original, donc 101 a le bit le plus significatif à 1. Le nombre est négatif et écrit sous sa forme de complément à deux.
Le complément à deux de 101 est 011, ce qui correspond à 3. Le nombre 101 représente –3, comme vous pouvez le voir dans la troisième colonne de la Figure 5.12. Un examen attentif de la figure montre que même si le complément à deux n'est pas la méthode la plus intuitive, c'est la plus efficace. Puisque nous n'avons qu'une seule représentation de 0, nous pouvons voir sur la figure qu'avec trois bits, la méthode du complément à deux peut représenter jusqu'à –4, ce que nous n'avons pas trouvé dans les deux autres méthodes.
Un autre problème important avec le complément à deux est que son implémentation matérielle est très efficace car nous pouvons utiliser le même matériel pour l'addition et la soustraction, et pour les entiers signés et les entiers non signés (unsigned integer). Par conséquent, une présentation en complément à deux d'un nombre signé est la présentation standard dans tous les systèmes informatiques (computer system).
Avec n bits, la plage de nombres qui peut être présentée est [–2n – 1, +2n – 1 – 1]. Vous pouvez voir que cette plage contient 2n nombres différents, exactement comme les nombres entiers non signés de n bits. La seule différence est que dans la plage signée, la moitié de la plage est négative, tandis que dans un entier non signé, toute la plage est positive.
Enfin, examinons comment les additions et les soustractions sont effectuées. Le processus est similaire à celui d'un nombre décimal en commençant par la droite et un éventuel report se propage vers la gauche. De plus, la soustraction n'est rien d'autre qu'une addition ; c'est-à-dire que A – B est identique à A + le complément à deux de B. Lorsque nous additionnons deux nombres en décimal, c'est simple. Avec le binaire, c'est aussi simple. Rappelez-vous simplement les informations du Tableau 5.2 ; op1 et op2 sont les deux entrées de l'opération d'addition.
| Op1 | Op2 | Retenue | Somme |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 |
Appliquons cela à des nombres de plus d'un bit. Dans la Figure 5.13, le côté gauche de l'exemple est une addition décimale traditionnelle, effectuée à la main sur papier. Le côté droit de l'exemple montre ce que font les ordinateurs. Les ordinateurs, comme nous le savons maintenant, n'utilisent que des 1 et des 0. Ainsi, s'ils ajoutent 1 à 1, par exemple, le résultat n'est pas 2 car les ordinateurs ne connaissent pas 2. Le résultat de 1 + 1 est 10, qui est la représentation binaire de 2. De ce 10, le 0 est le résultat et 1 est utilisé comme retenue.
Réfléchissez-y
Pourquoi les entiers ?
Un nombre réel, représenté sur un ordinateur comme un nombre à virgule flottante en simple précision, occupe quatre octets. Un entier occupe également quatre octets. Pourtant, la plage de nombres qu'un nombre à virgule flottante peut représenter est beaucoup plus grande que celle d'un entier.
- Pourquoi utilisons-nous un entier en premier lieu ?
Les ordinateurs sont beaucoup plus lents à traiter les nombres à virgule flottante car le matériel pour un nombre à virgule flottante est beaucoup plus compliqué que celui pour un entier, et il est préférable d'accélérer les choses en effectuant des calculs avec un entier. Nous n'utilisons également les nombres à virgule flottante que si c'est une nécessité absolue.
Représentation des caractères
N'oubliez pas que ce qui est stocké dans l'ordinateur n'est pas seulement des entiers. Si vous regardez un clavier, vous voyez un tas de caractères, de chiffres et de symboles, et lorsque vous appuyez sur une touche, ce symbole apparaît à l'écran. Mais comment les ordinateurs reconnaissent-ils ces caractères et les traitent-ils ?
Chaque caractère imprimable et non imprimable du clavier possède un code unitaire ou un nombre binaire unique. Ces codes sont connus sous le nom de code américain normalisé pour l'échange d'information (ASCII) (American Standard Code for Information Interchange (ASCII)). Les lettres majuscules ont des codes différents des lettres minuscules. Par exemple, « A » a un code différent de « a ». Les chiffres décimaux ont également leur propre code. Le code est de 7 bits, ce qui couvre 128 caractères. Ce codage a été étendu à 8 bits pour englober également les caractères non imprimables (c'est-à-dire les caractères du clavier qui ne peuvent pas être affichés à l'écran : pouvez-vous les deviner ?). La raison d'avoir des codes standardisés sur toutes les machines est de permettre aux ordinateurs de différentes marques, spécifications et tailles de travailler ensemble. Ce code a été approuvé en 1963, avant l'existence des ordinateurs personnels, puis révisé en 1965, 1967, 1968, 1977 et 1986. Aujourd'hui, tous les ordinateurs utilisent ce code pour représenter les caractères.
Vous réaliserez peut-être que 128 caractères, ou même 256, ne peuvent pas inclure toutes les langues écrites, c'est pourquoi il existe de nouvelles normes de codage telles que l'Universal Coded Character Set (UCS) et Unicode qui englobent toutes les langues écrites et intègrent l'ASCII comme les 128 premiers codes, ce qui assure une compatibilité ascendante, permettant l'intégration avec les anciens systèmes hérités.
Nombres réels (à virgule flottante)
Il n'y a pas d'ordinateur digne de ce nom qui ne puisse présenter et manipuler des nombres réels. Un nombre réel, tel que 3.14, est aussi appelé un nombre à virgule flottante (floating point number) car il y a une virgule décimale quelque part au milieu. Dans la plupart des langages de haut niveau (HLL), un nombre à virgule flottante en simple précision nécessite quatre octets de stockage, tout comme les entiers (integers) (signés et non signés).
Commençons par une question simple : si l'on nous donne un nombre binaire à virgule flottante, par exemple 1010.010101, comment obtenons-nous l'équivalent décimal ? La Figure 5.14 illustre comment les nombres binaires fractionnaires sont représentés. Nous utilisons la même technique que pour obtenir l'équivalent décimal d'un entier non signé. La seule différence est que les chiffres à droite, après la virgule flottante, ont des rangs négatifs commençant par –1. Si nous avons un nombre tel que 11.111, le rang du premier chiffre après la virgule flottante est –1, le suivant est –2, et le plus à gauche est –3. Les chiffres à gauche de la virgule flottante ont le rang habituel qui commence à 0. Par conséquent, l'équivalent décimal de 11.111 = 21 + 20 + 2–1 + 2–2 + 2–3 = 2 + 1 + 0.5 + 0.25 + 0.125 = 3.875.
Lien interactif
La meilleure façon d'avoir une vue claire de la manière dont les nombres sont traduits en binaire afin que les ordinateurs puissent les traiter est de voir le processus en action. Visitez ce site pour convertir n'importe quel nombre de la virgule flottante au binaire et vice versa et pour en savoir plus sur la façon de le faire manuellement.
Mais comment stockons-nous des nombres comme 11.111 dans la mémoire ou le registre de l'ordinateur ? La difficulté réside dans la position de la virgule flottante elle-même, car elle n'est pas connue à l'avance et peut changer pendant les calculs, ce qui rend très difficile de décider combien de bits réserver pour les chiffres à droite de la virgule flottante et les chiffres à gauche des virgules flottantes (floating point). Si nous essayons d'en faire un nombre fixe, disons 16 bits et 16 bits, nous n'obtenons pas une bonne précision. En revenant à la représentation mathématique des nombres décimaux à virgule flottante, vous vous souvenez peut-être que nous pouvons déplacer la virgule flottante vers la gauche ou vers la droite et conserver la valeur finale inchangée en multipliant par 10 à une certaine puissance. Par exemple, 1.875 est identique à 18.75 × 10–1, ce qui est identique à 1875 × 10–3, ce qui est identique à 0.1875 × 10, et ainsi de suite. En binaire, nous pouvons faire de même en multipliant par 2 à la puissance de quelque chose. Le nombre 11.111 est identique à 111.11 × 2–1 et ainsi de suite. En fait, nous pouvons exprimer n'importe quel nombre binaire à virgule flottante sous la forme 1.xxxx × 2y. Sauf cas particuliers, comme 0, l'expression de tout nombre binaire dans ce format nécessite le stockage de trois informations :
- Le bit de signe spécifiant si le nombre entier est positif (bit de signe 0) ou négatif (bit de signe 1)
- L'exposant (le y dans 1.xxxx × 2y)
- La partie fractionnaire (le xxxx dans 1.xxxx × 2y)
Notez que nous n'avons pas besoin de stocker le « 1. » car nous savons qu'il existe, sauf dans certains cas particuliers. Et c'est pourquoi l'un des noms du format à virgule flottante est « la technique du 1 caché ». Si nous parlons de virgule flottante en simple précision, elle occupe 4 octets (32 bits) et le format est montré dans la Figure 5.15. Un bit est nécessaire pour le signe, 8 bits pour l'exposant, et le reste (32 bits) pour la partie fractionnaire. Ce format est appelé format IEEE 754 (IEEE 754), développé par l'Institute of Electrical and Electronics Engineers (IEEE). C'est le format standard utilisé par presque tous les ordinateurs qui supportent les virgules flottantes, à très peu d'exceptions près.
Il y a une complexité concernant l'exposant — le bit de signe est responsable du signe du nombre entier. Mais qu'en est-il de l'exposant ? Nous devons pouvoir avoir des exposants positifs et négatifs. Si nous utilisons le format de complément à deux pour l'exposant, l'ensemble du format à virgule flottante devient excessivement compliqué. Le matériel qui gère les opérations à virgule flottante est très compliqué et beaucoup plus lent que celui qui gère les entiers, et nous ne voulons pas le rendre encore plus compliqué. La solution est de décaler la plage des nombres présentés par les 8 bits de l'exposant. Qu'est-ce que cela signifie ? Avec 8 bits, nous pouvons présenter des nombres de 0 à 256. Et si nous soustrayions 127 de chaque nombre ? C'est-à-dire que vous lisez les 8 bits, obtenez l'équivalent décimal (de la même manière qu'un entier non signé (unsigned integer)), puis soustrayez 127. Le résultat sera que la plage qui peut être présentée est maintenant de –127 à +128. Vous avez compris l'idée.
Un autre nom pour le format IEEE 754 (IEEE 754) est « excès 127 ». Notez que 127 est pour la simple précision. Pour la double précision qui prend 64 bits, nous soustrayons 1023, ce qui représente environ la moitié de la plage. La double précision est montrée en bas de la Figure 5.15. Voyons un exemple. Quel est l'équivalent décimal de 10111011010110000…0 ?
- Premièrement, divisons-le en ses trois composants principaux : signe, exposant et partie fractionnaire. Cela donne : 1 01110110 10110000…0.
- Le bit de signe est 1, donc le nombre entier est négatif.
- Exposant = 01110110. Son équivalent décimal est 118. Nous soustrayons 127. Cela donne l'exposant : 118 – 127 = –9.
- Le reste est la partie fractionnaire, mais nous devons ajouter le un caché, donc 1011000…0 devient 1.1011, ce qui a un équivalent décimal de 1 + 2–1 + 2–3 + 2–4 = 1.6875.
- Cela donne le nombre entier = –1.6875 × 2–9.
Avant de terminer notre discussion sur les virgules flottantes, il y a la question du 0. Comment présenter le 0 ? Même si nous mettons tous les bits à 0, le 1 caché rend la valeur finale non nulle. Comment pouvons-nous résoudre ce problème ? L'approche de représentation que nous avons apprise jusqu'à présent est appelée l'encodage normalisé du format IEEE 754. Ceci est utilisé si l'exposant est non nul et n'est pas 11111111. Si l'exposant est 0 (c'est-à-dire 00000000), nous sommes en encodage dénormalisé (également appelé subnormal). Lorsque nous sommes dans ce cas particulier, il y a quelques différences dans la traduction en décimal :
- L'exposant est à polarisation 1 au lieu de polarisation 0. La polarisation est de 127 en simple précision et de 1023 en double précision.
- Il n'y a pas de 1 caché, donc la partie fractionnaire est 0.xxxx (les 23 bits de la partie fractionnaire en simple précision) au lieu de 1.xxxx….
Avec ces exceptions, nous ne pouvons pas présenter le 0 (sauf en mettant tous les 32 bits à 0) mais nous pouvons présenter de très petits nombres.
Le cas où l'exposant est composé uniquement de 1 est appelé « encodage des valeurs spéciales ». Si l'exposant est composé uniquement de 1 et que la partie fractionnaire est composée uniquement de 0, cela représente l'infini. Si l'exposant est composé uniquement de 1 et que la partie fractionnaire est non nulle, cela est appelé NaN (Not a Number) et lève une exception. Cela se produit lorsqu'il y a un bogue dans votre programme qui effectue une division par 0 ou la racine carrée de –1, par exemple.