Entiers relatifs
entier = int(input('Entrez une valeur entière en base 10 : '))
if entier >=0: # entier positif ou nul ?
comp_2 = '0'+ bin(entier)[2:] # on convertit simplement l'entier en chaîne binaire, en rajoutant un bit de signe à 0 au début
else : # entier négatif ?
val_absolue = - entier # on prend l'opposé de l'entier pour avoir sa valeur absolue
binaire = '0'+ bin(val_absolue)[2:] # chaîne initialisée avec le codage de l'entier positif ( idem ci-dessus )
inverse = '' # chaîne qui stockera le résultat de l'inversion des bits de l'entier
for bit in binaire : # parcours des bits pour les inverser
if bit == '0':
inverse = inverse + '1'
else :
inverse = inverse + '0'
ajout_1 = int('0b'+inverse,2) + 1 # addition de 1 à la chaîne inversée après sa conversion en base 10
comp_2 = bin(ajout_1)[2:] # conversion du résultat en binaire
print("En complément à deux,", str(entier),"se code :",comp_2)
On code chaque cas identifié dans l'étude préalable, en distinguant les 2 situations où il y a, ou pas, déjà une retenue à prendre en compte :
Retenue | Bit 1 | Bit 2 | Résultat |
---|---|---|---|
0 | 0 | 0 | S = 0 R = 0 |
0 | 1 | 0 | S = 1 R = 0 |
0 | 0 | 1 | S = 1 R = 0 |
0 | 1 | 1 | S = 0 R = 1 |
1 | 0 | 0 | S = 1 R = 0 |
1 | 1 | 0 | S = 0 R = 1 |
1 | 0 | 1 | S = 0 R = 1 |
1 | 1 | 1 | S = 1 R = 1 |
b1 = input('Entrez une première valeur binaire à 8 bits : ')
b2 = input('Entrez une deuxième valeur binaire à 8 bits : ')
addition ='' # chaîne qui contiendra le résultat de l'addition
retenue = 0 # entier pour le stockage de la retenue
for i in range(7,-1,-1) : # parcours des deux valeurs binaires "à l'envers", c.à.d. du LSB ( index = 7 ) au MSB ( index = 0 )
if retenue == 0: # pas de retenue
if (b1[i] == '0' and b2[i] == '0'):
addition = '0' + addition
retenue = 0
elif (b1[i] == '1' and b2[i] == '0'):
addition = '1' + addition
retenue = 0
elif (b1[i] == '0' and b2[i] == '1'):
addition = '1' + addition
retenue = 0
elif (b1[i] == '1' and b2[i] == '1'):
addition = '0' + addition
retenue = 1
else : # retenue
if (b1[i] == '0' and b2[i] == '0'):
addition = '1' + addition
retenue = 0
elif (b1[i] == '1' and b2[i] == '0'):
addition = '0' + addition
retenue = 1
elif (b1[i] == '0' and b2[i] == '1'):
addition = '0' + addition
retenue = 1
elif (b1[i] == '1' and b2[i] == '1'):
addition = '1' + addition
retenue = 1
print("Le résultat de l'addition binaire est :", str(retenue) + addition)
range()
à bien préciser un pas de -1 (3ème paramètre) et à ne pas oublier que la variable compteur n'ira pas jusqu'au deuxième paramètre; il faut donc mettre -1 en deuxième paramètre
pour que le compteur aille effectivement jusqu'à zéro...Étrange ? Non, logique, ça marche comme ça !while()
, c'est peut-être plus clair :
i = 7
while (i >= 0):
........
........
i = i - 1
Vous aviez sûrement remarqué que finalement, il n'existe pas tant de cas différents possibles : par exemple, les deux cas où un seul des bits parmi les deux à additionner est égal à 1 conduisent en fait à la même situation, à savoir : l'addition vaut '0', et la retenue prend la valeur 1. On peut donc regrouper ces deux situations pour évaluer "en même temps" une de ces conditions OU l'autre :
if (b1[i] == '1' and b2[i] == '0') or (b1[i] == '0' and b2[i] == '1'):
Mais on peut aller plus loin dans la simplification. Après étude attentive du tableau ci-dessus, on s'aperçoit qu'on peut réduire le problème à seulement 4 cas différents :
Cas | Bit 1 | Bit 2 | Retenue |
---|---|---|---|
S = 0 R = 0 |
0 | 0 | 0 |
S = 1 R = 0 |
1 | 0 | 0 |
0 | 1 | 0 | |
0 | 0 | 1 | |
S = 0 R = 1 |
1 | 1 | 0 |
1 | 0 | 1 | |
0 | 1 | 1 | |
S = 1 R = 1 |
1 | 1 | 1 |
Et que remarque-t-on alors ?
Cas | Valeurs des 3 bits |
---|---|
S = 0 R = 0 |
les 3 bits valent 0 |
S = 1 R = 0 |
1 des 3 bits vaut 1 |
S = 0 R = 1 |
2 bits parmi les 3 valent 1 |
S = 1 R = 1 |
Les 3 bits valent 1 |
Du coup, il suffit de déterminer le nombre de bit(s) qui valent 1, et on pourra en déduire très simplement la valeur de la somme et de la retenue !
Pour trouver ce nombre, on peut par exemple calculer la valeur de la somme de ces trois bits ( après les avoir transtypés en type int
bien entendu ), et selon la valeur de cette somme, déterminer les valeurs
de l'addition des bits et de la retenue :
b1 = input('Entrez une première valeur binaire à 8 bits : ')
b2 = input('Entrez une deuxième valeur binaire à 8 bits : ')
addition ='' # chaîne qui contiendra le résultat de l'addition
retenue = 0 # entier pour le stockage de la retenue
for i in range(7,-1,-1) : # parcours des deux valeurs binaires "à l'envers", c.à.d. du LSB ( index = 7 ) au MSB ( index = 0 )
somme = int(b1[i]) + int(b2[i]) + retenue # calcul de la somme des 3 bits
if somme == 0: # les 3 bits à 0
addition = '0' + addition
retenue = 0
elif somme == 1: # 1 bit à 1
addition = '1' + addition
retenue = 0
elif somme == 2: # 2 bits à 1
addition = '0' + addition
retenue = 1
else : # les 3 bits à 1
addition = '1' + addition
retenue = 1
print("Le résultat de l'addition binaire est :", str(retenue) + addition)
Oui, il fallait y penser...mais c'est en analysant et raisonnant avant de coder que l'on peut ainsi simplifier des situations qui apparaissent a priori complexes : en informatique, on peut très souvent réduire un problème complexe à un ensemble de sous-problèmes beaucoup plus simples à traiter...