Dans ce chapitre, on se pose la question de savoir comment on écrira un nombre entier négatif dans un ordinateur. Les choix que l'on fera sont au lié au fait que dans l'ordinateur, un nombre ne sera écrit que avec des 0 et des 1 et avec une taille fixe.
Notation : Quand j'écrirai [1110 1001], je parlerai d'un octet tel qu'écrit dans la machine, sans me soucier de la signification de cet octet.
L'octet [1110 1001], par exemple, n'a a priori aucune signification. Il pourrait représenter le nombre 233, le nombre -23 ou encore le caractère é. Quand on lit un octet (ou un groupe d'octets) on doit toujours savoir de type de donnée il s'agit afin d'interpréter les bits correctement.
Voici notre problème : nous ne disposons que de 0 et de 1. Comment allons-nous indiquer que l'on veut un signe négatif ?
Bien que cette idée soit valable, ce n'est pas ainsi que l'on fait !
On peut décider d'utiliser le premier bit du nombre comme bit de signe. On dirait alors :
Cette solution est simple mais elle n'est pas utilisée car elle est a un défaut que l'on donnera plus loin.
Si on utilisait cette méthode – J'insiste, on va faire autrement !
[0010 1111] représente le nombre +010 1111 en binaire donc 47.[1010 1111] représente le nombre -010 1111 en binaire donc –47.Supposons que je dispose de 8 bits pour stocker des nombres. Dans un contexte ou je n'ai pas besoin de nombres négatifs, je ne veux pas m'embarrasser d'un bit de signe qui me fait gaspiller 1 bit. Mais si je pense avoir besoin de nombres négatifs, le bit de signe m'intéresse.
On veut pouvoir choisir notre mode de fonctionnement :
Supposons alors que je veuille faire le calcul S = A + B dans différents cas.
On ne souhaite pas utiliser de nombres négatifs. On code donc les entiers en mode positif.
Cette fois on veut utiliser des nombres signés et donc pouvoir indiquer s'ils sont positifs ou négatifs. On décide d'utiliser le bit de signe comme présenté plus haut.
Quel est le problème ?
Alors on codera A par [1000 0011] et B par [0000 0111]. Le résultat sera S = 138 ce qui sera codé par [1000 1010].
Alors, si on adopte le bit de signe, A sera codé [1000 0011] et B sera codé [0000 0111]. Le résultat, S = 4, sera codé [0000 0100].
Dans les deux cas
Mais le codage du résultat est différent. Cela signifie que la table de vérité du circuit faisant l'addition n'est pas la même dans les deux cas. Cela signifie qu'il faut deux circuits électronique additionneur, un circuit pour chaque cas de codage.
Ma voiture a 453 725 km au compteur. Le compteur affiche 6 chiffres. Je ne compte pas le chiffre des dixièmes.
Je veux ramener le compteur à 000 000 km mais sans trafiquer le compteur, seulement en roulant. Est-ce possible ? Comment ?
Solution : En roulant encore 546 274 km, le compteur affichera 999 999 km. Encore 1 km et le compteur fait un tour, il revient à 000 000 km.
Donc, comme le compteur n'a que 6 chiffres et que l'on ne peut pas savoir qu'il a fait un tour, tout se passe comme si on avait fait le calcul :
[453 725] + [546 275] = [000 000]
C'est à dire : [546 275] = - [453 725]
C'est cette idée que le CA2 va exploiter.
0, c'est un nombre positif, en binaire naturel.[0011 0101] correspond à $0011\:0101_b = 53$1, c'est un nombre négatif. Il n'est pas en binaire naturel !.
Exemple de nombre négatif : [1011 0101] correspond à un nombre négatif. On ne peut pas le lire directement. Il faut :
[0100 1010][0100 1011]. Ce nouveau nombre est en CA2 et il correspond à $0100\:1011_b = 73$.[1011 0101] correspond donc à $-73$.
Le python utilise des entiers codé en CA2 sur 4 octets.
On peut inverser avec ~ de sorte que si on écrit ~45 + 1 on obtient -45.
On reconnaît bien le CA2.
Le CA2 est construit autour de l'idée du tour de compteur. Il utilise donc l'addition normalement. On va voir que le problème soulevé plus haut ne se pose plus.
Exercice
Reprenons donc le calcul S = A + B
Même chose que précédemment.
[1000 0011],[0000 0111],[1000 1010].On utilise des nombres signés. Il nous faut donc une méthode pour représenter le signe. On décide d'utiliser le CA2.
En quoi est-ce mieux que le cas précédent ?
[1000 0011],[0000 0111],[1000 1010].Dans les deux cas,
Peu importe ce que représentent ces octets, que ce soit un nombre positif ou un nombre en CA2, l'important est que dans les deux cas, la table de vérité du circuit est la même et donc un seul circuit suffira pour additionner les nombres, peu importe qu'ils soient signés ou non.
Considérons un octet. Il représente un nombre entier en binaire naturel.
Donnez l'entier correspondant à ces octets en CA2 :
[0000 0000][0001 1011][1010 1100][1111 1111][0111 1111][1000 0000]Quels sont les nombres maximum et minimum pouvant être codés sur un octet en CA2 ?
Coder en CA2 les entiers suivants :
Le dernier cas pose un problème, lequel ?