Aller au contenu

TP - Conversions par complément à 2

Dans le dossier [NSI], créez le dossier [A03-Entiers relatifs].

Téléchargez le fichier « à trous » TPA03.11.py (clic droit -> [Enregistrer la cible du lien sous]) et enregistrez-le dans ce dossier.

Consignes communes à chaque partie

Le programme principal contient un appel au module doctest :

##----- Programme principal et tests -----##
if __name__ == '__main__':
    import doctest
    doctest.testmod()
Un test est donné dans le docstring de chaque fonction.
Il faudra ajouter un plan de test (avec affichage) des fonctions dans le programme principal.
Pensez à demander au professeur de vous aider pour écrire et valider ce plan de test...

Partie A - Fonctions utiles

Cette partie a pour objectif de vous faire programmer les fonctions intermédiaires utilisées lorsqu'on sauhaite mettre en œuvre un des algorithmes de conversion de représentation par complément à 2.

Attention aux effets de bord !

  1. Complétez le corps de la fonction echange_bits() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    def inverse_bits(tab):
        """
        tab – list, tableau d'éléments valant 0 ou 1
        Sortie: None – chaque bit valant 1 est remplacé par 0,
                chaque bit valant 0 est remplacé par 1
                (fonction à "effet de bord")
    
        >>> tab1 = [1, 0, 1, 1]
        >>> echange_bits(tab1)
        >>> tab1
        [0, 1, 0, 0]
    
        >>> tab2 = [1, 1, 1, 1]
        >>> echange_bits(tab2)
        >>> tab2
        [0, 0, 0, 0]
        """
    

  2. Copiez/collez et complétez le corps de la fonction ajoute1() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    def ajoute1(tab):
        """
        tab – list, tableau d'éléments valant 0 ou 1
        Sortie: None – ajoute en binaire 1 au dernier élément de
                tab et reporte la retenue jusqu'au premier élément
                La dernière retenue est « perdue »
                (fonction à "effet de bord")
    
        >>> tab1 = [1, 0, 1, 1]
        >>> ajoute1(tab1)
        >>> tab1
        [1, 1, 0, 0]
    
        >>> tab2 = [1, 1, 1, 1]
        >>> ajoute1(tab2)
        >>> tab2
        [0, 0, 0, 0]
        """
    

    Une piste

    Comment parcourir les éléments du tableau ? du premier au dernier ou bien du dernier au premier ?

    Une autre piste

    Faut-il parcourir tous les éléments du tableau ?
    Dans quelle situation est-il inutile de tout parcourir ?

  3. Copiez/collez et complétez le corps de la fonction est_dans_plage() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    def est_dans_plage(n, nb_bits):
        """
        n - int, entier relatif
        nb_bits - int, entier strictement positif
        Sortie: booléen – renvoie True si n appartient à la plage de représentation
                par complément à 2 sur nb_bits bits, renvoie False sinon
    
        >>> est_dans_plage(243, 8)
        False
    
        >>> est_dans_plage(-112, 8)
        True
        """
    

    Une piste

    Vous connaissez le nombre de bits de la représentation donc vous pouvez déterminer les valeurs du plus petit et du plus grand nombre entier dans cette représentation.

Partie B - Conversion d'entiers positifs

Lorsque l'entier à représenter est positif (et que cet entier est dans la plage de représentation) alors, on utilise l'algorithme usuel de représentation binaire des entiers positifs.

  1. Copiez/collez et complétez le corps de la fonction binaire_usuel() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    def binaire_usuel(n, nb_bits):
        """
        n – int, entier positif ou nul
        nb_bits – int, entier strictement positif
        Sortie: list – tableau de nb_bits bits de valeur 0 ou 1.
                Correspond à l'écriture binaire de n dans l'ordre
                Par exemple, 15 est représenté sur un octet par (0000 1111)
                donc la fonction doit renvoyer [0, 0, 0, 0, 1, 1, 1, 1]
    
        >>> binaire_usuel(15, 8)
        [0, 0, 0, 0, 1, 1, 1, 1]
        >>> binaire_usuel(225, 16)
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1]
        """
    

    Une piste

    Testez les instructions suivants dans la console, elles pourraient vous aider :

    >>> tab = [0, 1, 1, 0]
    >>> tab = tab + [0]
    
    >>> tab = [0] + tab
    
  2. Copiez/collez et complétez le corps de la fonction entier_positif() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    def entier_positif(tab):
        """
        tab – list, tableau d'éléments valant 0 ou 1
        Sortie: int – entier positif dont la représentation binaire usuelle est tab.
                Par exemple l'octet [0, 0, 0, 0, 1, 1, 1, 1] représente l'entier
                positif 15 dont la valeur est renvoyée par la fonction.
    
        >>> entier_positif( [0, 0, 0, 0, 1, 1, 1, 1] )
        15
        >>> entier_positif( [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1] )
        225
        """
    

    Une piste

    Posez-vous les questions suivantes :

    1. Faut-il parcourir de gauche à droite ou de droite à gauche ?
    2. Comment définir la puissance de 2 qui correspond à chaque rang ?

Partie C - Conversion d'entiers relatifs

Cette dernière partie va nécessiter d'avoir recours aux fonctions programmées dans les parties précédentes.

Une piste

N'oubliez pas les algorithmes étudiées (et appris) en classe...

  1. Copiez/collez et complétez le corps de la fonction complement_a2() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    def complement_a2(n, nb_bits):
        """
        n – int, entier relatif représentable sur nb_bits
        nb_bits – entier strictement positif
        Sortie: list – tableau de nb_bits bits de valeur 0 ou 1.
                Représentation en complément à 2 de n sur nb_bits bits
                Si n n'est pas représentable sur nb_bits bits, renvoie None
    
        >>> complement_a2(-112, 8)
        [1, 0, 0, 1, 0, 0, 0, 0]
    
        >>> complement_a2(145, 8)
    
        """
    

  2. Copiez/collez et complétez le corps de la fonction entier_relatif() en respectant ses spécifications.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    def entier_relatif(tab):
        """
        tab – list, tableau d'éléments valant 0 ou 1
        Sortie: int – entier relatif dont la représentation en
                complément à deux sur len(tab) bits est tab.
    
        >>> entier_relatif([1, 0, 0, 1, 0, 0, 0, 0])
        -112
    
        >>> entier_relatif([0, 1, 0, 1, 0, 0, 0, 0])
        80
        """
    

  3. Réalisez un plan de test complet de chacune des fonctions dans le programme principal (le « main »).