bin(123)'0b1111011'
bin(), hex() et int().>>> bin(123)
>>> int("0b1111")
>>> int("0b10101", 2)
>>> bin(0)
>>> int("0b101211", 2)
>>> hex(2022)
>>> int("0xABC", 16)
Le but de cet exercice est d’étudier une fonction permettant de convertir en base 2 un nombre entier naturel donné en base 10.
On donne ci-dessous le code de la fonction dec_to_bin :
Tester cette fonction avec quelques valeurs de \(n\) et vérifier qu’elle effectue bien la conversion attendue.
Quel est la méthode utilisée ? Faire le lien avec un des exemples du cours.
On souhaite convertir le nombre \(n=105\) en binaire. Recopier et compléter le tableau d’état des variables lors de l’appel dec_to_bin(105). L’étape zéro correspond à l’initialisation, l’étape 1 à l’état des variables après le premier passage dans la boucle while.
| Etape | chaine_bin |
nombre |
r |
|---|---|---|---|
| 0 | “” | 102 | / |
| 1 | … | … | … |
Modifier la fonction afin que le préfixe 0b soit présent dans la chaîne retournée.
La méthode utilisée est celle des divisions successives en conservant les restes. C’est la méthode utilisée dans le cours.
Tableau d’exécution pour \(n=105\) :
| Etape | chaine_bin |
nombre |
r |
|---|---|---|---|
| 0 | “” | 105 | / |
| 1 | “1” | 52 | 1 |
| 2 | “01” | 26 | 0 |
| 3 | “001” | 13 | 0 |
| 4 | “1001” | 6 | 1 |
| 5 | “01001” | 3 | 0 |
| 6 | “101001” | 1 | 1 |
| 7 | “1101001” | 0 | 1 |
Écrire une fonction qui respecte les spécifications indiquées :
Écrire une fonction analogue add_3_bits(a, b, c) qui retourne la somme de trois bits.
def add_2_bits(a: int, b: int) -> str:
"""a et b sont des bits égaux à 0 ou 1
retourne une chaine représentant en base 2
la somme de a et de b"""
if a == 1 and b == 1:
rep = "10"
elif a == 1 or b == 1:
rep = "1"
else:
rep = "0"
return rep
# Vérification
assert add_2_bits(0,0) == "0"
assert add_2_bits(1,0) == "1"
assert add_2_bits(0,1) == "1"
assert add_2_bits(1,1) == "10"def add_3_bits(a: int, b: int, c: int) -> str:
if a == 1 and b == 1:
if c == 1:
return "11"
else:
return "10"
elif a == 1 or b == 1:
if c == 1:
return "10"
else:
return "1"
else:
if c == 1:
return "1"
else:
return "0"
# Vérification
assert add_3_bits(0,0,0) == "0"
assert add_3_bits(1,0,0) == "1"
assert add_3_bits(0,1,0) == "1"
assert add_3_bits(0,0,1) == "1"
assert add_3_bits(0,1,1) == "10"
assert add_3_bits(1,0,1) == "10"
assert add_3_bits(1,1,0) == "10"
assert add_3_bits(1,1,1) == "11"Coder la fonction complement_deux spécifiée ci-dessous. Vous pourrez utiliser la fonction dec_to_bin définie à l’exercice 2 (sans le préfixe 0b). Votre code devra tester les préconditions indiquées sur l’entier \(n\).
Un jeu de tests unitaires est proposé ci-dessous : il permet de vérifier que votre fonction retourne bien ce qui est attendu.
def complement_deux(n:int, nbits:int)->str:
"""
Renvoie la notation en compléments à 2 de l'entier relatif n
sous la forme d'une chaîne de caractères
Parameters
----------
n : int Précondition -2**(nbits-1) <= n < 2**(nbits-1)
nbits : int
Returns
-------
type str de longueur nbits
"""
pass
print(complement_deux(-12,8))
# Jeu de tests unitaires
assert complement_deux(0, 8) == "00000000"
assert complement_deux(5, 8) == "00000101"
assert complement_deux(2**7 - 1, 8) == "01111111"
assert complement_deux(-2**7, 8) == "10000000"
assert complement_deux(2**7 - 2, 8) == "01111110"
assert complement_deux(-2**7 + 1, 8) == "10000001"
assert complement_deux(-1, 8) == "11111111"
assert complement_deux(-2, 8) == "11111110"
print("Bravo ! Tous les tests sont réussis !")Sortie attendue à l’exécution :
11110100
Bravo ! Tous les tests sont réussis !
def complement_deux(n:int, nbits:int)->str:
"""
Renvoie la notation en compléments à 2 de l'entier relatif n
sous la forme d'une chaîne de caractères
Parameters
----------
n : int Précondition -2**(nbits-1) <= n < 2**(nbits-1)
nbits : int
Returns
-------
type str de longueur nbits
"""
# Vérification de préconditions
assert type(n) == int and (-2**(nbits-1) <= n < 2**(nbits-1))
assert type(nbits) == int
if n >=0: # n est positif
rep = dec_to_bin(n)
else: # n est négatif
cplt = 2**nbits - abs(n)
rep = dec_to_bin(cplt)
# On complète la chaîne pour arriver à nbits
while len(rep) < nbits:
rep = "0" + rep
return rep
print(complement_deux(-12,8))
# Jeu de tests unitaires
assert complement_deux(0, 8) == "00000000"
assert complement_deux(5, 8) == "00000101"
assert complement_deux(2**7 - 1, 8) == "01111111"
assert complement_deux(-2**7, 8) == "10000000"
assert complement_deux(2**7 - 2, 8) == "01111110"
assert complement_deux(-2**7 + 1, 8) == "10000001"
assert complement_deux(-1, 8) == "11111111"
assert complement_deux(-2, 8) == "11111110"
print("Bravo ! Tous les tests sont réussis !")11110100
Bravo ! Tous les tests sont réussis !
Écrire une fonction ieee_754(x) qui prend en entrée un flottant x (en base 10) et qui retourne une chaine de caractères correspondant à la représentation de \(x\) selon la norme IEEE-754 sur 32 bits.
Conseils : vous pourrez décomposer le problème en plusieurs fonctions séparées pour traiter les étapes une par une.
def ieee_754(x: float) -> str:
"""Convertit le flottant x en binaire selon la norme ieee 754 sur 32 bits
Résultat retourné sous forme de chaîne de caractères"""
# bit de signe
if x >= 0:
chaine = "0 "
else:
chaine = "1 "
n = abs(int(x)) # partie entière de x
f = abs(x) - n # partie décimale de x
n_bin = dec_to_bin(n) # partir entière de x en binaire
# conversion en binaire de la partie décimale f, on se limite à 100 bits maximum
f_bin = ""
while f != 0 and len(f_bin) < 100:
f = 2 * f
f_bin = f_bin + str(int(f))
f = f - int(f)
# calcul de l'exposant
if n >= 1:
e = len(n_bin) - 1
# mantisse
m = n_bin[1:] + f_bin
else:
# cas d'un nombre de partie entière nulle
# on cherche le premier 1 dans la partie fractionnaire
e = 0
compteur = 0
while f_bin[compteur] == "0":
compteur += 1
e = - (compteur + 1)
m = f_bin[compteur+1:]
# codage de l'exposant
#print(f"exposant : {e}")
e = e + 127
e_bin = bin(e)[2:]
while len(e_bin) < 8:
e_bin = "0" + e_bin
chaine = chaine + e_bin + " "
# mantisse : on renvoie une mantisse de taille 23 bits
if len(m) > 23:
m = m[:23]
while len(m) < 23:
m = m + "0"
chaine = chaine + m
return chaine
# Vérification avec quelques exemples
nb = [0.9218, 0.002125, 45.218, 126.725, 0.1, 0.333333333333333333333333333, -2.5]
for item in nb:
print(f"codage de {item} : {ieee_754(item)}")codage de 0.9218 : 0 01111110 11010111111101100010101
codage de 0.002125 : 0 01110110 00010110100001110010101
codage de 45.218 : 0 10000100 01101001101111100111011
codage de 126.725 : 0 10000101 11111010111001100110011
codage de 0.1 : 0 01111011 10011001100110011001100
codage de 0.3333333333333333 : 0 01111101 01010101010101010101010
codage de -2.5 : 1 10000000 01000000000000000000000
Remarque : le site https://www.ultimatesolver.com/en/ieee-754 permet de vérifier ces réponses.