Un ordinateur ne manipule que des bits (0 ou 1). Tout nombre entier positif s'écrit en base 2 à l'aide des puissances de 2 : $$ (13)_{10} = 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = (1101)_2 $$
bin(13) renvoie '0b1101' ; int('1101', 2) renvoie 13.La base 16 utilise les chiffres 0 à 9 puis les lettres A à F (valeurs 10 à 15). Chaque chiffre hexadécimal correspond exactement à quatre bits : $$ (\mathtt{2F})_{16} = 2 \times 16^1 + 15 \times 16^0 = (47)_{10} = (0010\;1111)_2 $$
hex(47) renvoie '0x2f' ; int('2F', 16) renvoie 47.#FF8800), adresses mémoire, codes ASCII.A) à 90 (Z), les minuscules de 97 (a) à 122 (z), les chiffres de 48 (0) à 57 (9).ord('A') renvoie 65 ; chr(65) renvoie 'A'.Les nombres à virgule sont codés selon la norme IEEE 754. Un flottant sur 64 bits (type float en Python) se décompose en :
La conséquence principale est que la précision est finie : certains nombres décimaux simples comme $0{,}1$ ne sont pas représentables exactement.
ord() et chr() (l'une donne le code, l'autre le caractère).| Code erroné | Code correct | Explication |
|---|---|---|
bin(13) $\to$ 1101 | bin(13) $\to$ '0b1101' | bin() renvoie une chaîne préfixée par 0b, pas un entier. |
int('0b1101') $\to$ erreur | int('0b1101', 2) ou int('1101', 2) | Il faut préciser la base 2 en second paramètre effectif. |
chr('65') $\to$ TypeError | chr(65) $\to$ 'A' | chr() attend un entier, pas une chaîne. |
| Sur 8 bits, $200 + 100 = 300$ | Dépassement (overflow) : $300 > 255$ | Sur $n$ bits non signés, la valeur maximale est $2^n - 1$. |
# Décimal -> Binaire -> Hexadécimal
n = 42
print(bin(n)) # '0b101010'
print(hex(n)) # '0x2a'
# Binaire -> Décimal
print(int('101010', 2)) # 42
# Hexadécimal -> Décimal
print(int('2a', 16)) # 42
def decimale_vers_binaire(n):
"""Renvoie l'écriture binaire de n (entier positif) sous forme de chaîne."""
if n == 0:
return '0'
bits = ''
while n > 0:
bits = str(n % 2) + bits # le reste donne le bit
n = n // 2
return bits
print(decimale_vers_binaire(13)) # '1101'
print(decimale_vers_binaire(255)) # '11111111'
def binaire_vers_decimale(b):
"""Renvoie la valeur décimale de la chaîne binaire b."""
resultat = 0
for bit in b:
resultat = resultat * 2 + int(bit)
return resultat
print(binaire_vers_decimale('1101')) # 13
for code in range(65, 91):
print(f"{chr(code)} -> {code}", end=" ")
# A -> 65 B -> 66 C -> 67 ...
def complement_a_deux(n, bits=8):
"""Renvoie la représentation binaire en complément à deux sur 'bits' bits."""
if n >= 0:
return bin(n)[2:].zfill(bits)
else:
# Inverse les bits de |n| et ajoute 1
positif = bin(abs(n))[2:].zfill(bits)
inverse = ''.join('1' if b == '0' else '0' for b in positif)
return bin(int(inverse, 2) + 1)[2:].zfill(bits)
print(complement_a_deux(5)) # '00000101'
print(complement_a_deux(-5)) # '11111011'
Divisions successives par 2 :
Somme des puissances de 2 :
On regroupe les bits par paquets de quatre (de droite à gauche) :
On développe chaque chiffre hexadécimal en quatre bits :
decimale_vers_binaire(n) qui renvoie la représentation binaire d'un entier positif sous forme de chaîne, sans utiliser bin().binaire_vers_decimale(b) qui prend une chaîne binaire et renvoie l'entier correspondant, sans utiliser int(b, 2).decimale_vers_hexa(n) qui renvoie la représentation hexadécimale d'un entier positif sous forme de chaîne, sans utiliser hex().def decimale_vers_binaire(n):
if n == 0:
return '0'
bits = ''
while n > 0:
bits = str(n % 2) + bits
n = n // 2
return bits
def binaire_vers_decimale(b):
resultat = 0
for bit in b:
resultat = resultat * 2 + int(bit)
return resultat
def decimale_vers_hexa(n):
if n == 0:
return '0'
chiffres = '0123456789ABCDEF'
h = ''
while n > 0:
h = chiffres[n % 16] + h
n = n // 16
return h
Vérification :
decimale_vers_binaire(42) renvoie '101010' ;binaire_vers_decimale('101010') renvoie 42 ;decimale_vers_hexa(255) renvoie 'FF'.cesar(texte, decalage) qui applique le chiffrement de César à une chaîne de lettres majuscules. Chaque lettre est décalée de decalage positions dans l'alphabet (avec retour cyclique).cesar("BONJOUR", 3) qui doit renvoyer "ERQMRXU".def cesar(texte, decalage):
resultat = ''
for c in texte:
if 'A' <= c <= 'Z':
code = ord(c) - ord('A') # position 0..25
nouveau = (code + decalage) % 26 # décalage cyclique
resultat += chr(nouveau + ord('A'))
else:
resultat += c # caractère inchangé
return resultat
# Chiffrement
print(cesar("BONJOUR", 3)) # "ERQMRXU"
# Déchiffrement : on décale dans l'autre sens
def dechiffrer_cesar(texte, decalage):
return cesar(texte, -decalage)
print(dechiffrer_cesar("ERQMRXU", 3)) # "BONJOUR"
Principe : ord('B') - ord('A') = 1. En ajoutant le décalage 3, on obtient 4, soit chr(4 + 65) = 'E'. Le modulo 26 assure le retour cyclique (Z + 1 $\to$ A).
Vérification : B$\to$E, O$\to$R, N$\to$Q, J$\to$M, O$\to$R, U$\to$X, R$\to$U. ✓