Écrire une fonction oppose(s) qui, donnée une chaîne de bits en…
Exercice de TD · niveau 3 (difficile) · NSI (première), chapitre 1 — Représenter les entiers · Le complément à deux
Énoncé
Écrire une fonction oppose(s) qui, donnée une chaîne de bits en complément à deux, renvoie le codage de l'opposé — sans passer par la valeur décimale. Indication : inverser tous les bits puis ajouter . Justifier cette recette à partir de la définition, et déterminer la seule valeur pour laquelle elle échoue.
Corrigé
Pourquoi ça marche. Notons la valeur non signée de la chaîne, sur bits. Inverser tous les bits remplace chaque par un et réciproquement, donc transforme en : c'est la chaîne de uns moins , sans aucune retenue. En ajoutant , on obtient , c'est-à-dire modulo : exactement le codage de l'opposé.
def oppose(s):
"""Codage en complément à 2 de l'opposé de l'entier codé par s.
Précondition : s ne code pas -2**(n-1), dont l'opposé n'est
pas représentable sur n bits.
"""
inverse = ""
for c in s:
inverse = inverse + ("1" if c == "0" else "0")
return addition_base(inverse, "1", 2)[-len(s):]
La tranche finale [-len(s):] jette la retenue sortante — c'est la réduction modulo du théorème du cours.
Validation exhaustive sur , et bits, pour toutes les valeurs sauf la plus petite :
for n in (4, 8, 12):
for x in range(-2**(n - 1) + 1, 2**(n - 1)):
s = complement_a_2(x, n)
assert depuis_complement_a_2(oppose(s)) == -x
La valeur qui échoue. C'est , soit sur 8 bits. Son codage est 10000000 ; inversé il donne 01111111, plus : 10000000. La fonction rend l'entrée elle-même, et n'est effectivement pas représentable sur 8 bits — l'intervalle n'est pas symétrique.
Piège : y voir un bogue de la fonction. Ce n'en est pas un : c'est une limite du codage, qui possède un négatif de plus que de positifs. La fonction ne peut que la signaler, d'où la précondition.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.