Entiers relatifs

Représentation des entiers relatifs - Correction des applications

1. Complément à deux


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)
		

2. Addition binaire

Proposition de script : la méthode brute...

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)
			

Remarques :

Méthode plus judicieuse

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...