Cours complet — Python exécutable — Exercices progressifs — QCM interactif
Vus de l'extérieur, les ordinateurs manipulent des nombres, du texte, des images, du son. Mais à l'intérieur, chaque circuit électronique n'a que deux états possibles : le courant passe, ou il ne passe pas.
b est un moyen de représenter les nombres avec b symboles. Selon sa place, chaque symbole « pèse » une valeur particulière : le système est dit de position.
Pour représenter des nombres, du texte ou des images avec seulement deux états, il faut donc les écrire comme des suites de 0 et de 1 : c'est la base 2, ou système binaire.
Exemple : le mot 100 représente l'état d'un circuit composé de 3 circuits mémoire un bit, dont les états sont 1, 0 et 0.
1010 1010 (plus facile à lire que 10101010).
Quand un rang est plein, on passe au rang suivant — exactement comme en base 10, sauf qu'un rang binaire n'accepte que 0 ou 1.
| Décimal | Binaire |
|---|---|
| 0 | 0 |
| 1 | 1 |
| 2 | 10 |
| 3 | 11 |
| 4 | 100 |
| 5 | 101 |
| 6 | 110 |
| 7 | 111 |
| 8 | 1000 |
n bits, on peut coder exactement 2ⁿ valeurs différentes, c'est-à-dire les entiers de 0 à 2ⁿ − 1. Avec 1 bit : 2 valeurs. Avec 8 bits (1 octet) : 256 valeurs, de 0 à 255.
Comme en base 10 où 352 = 3×10² + 5×10¹ + 2×10⁰, en base 2 chaque position vaut une puissance de 2.
| 2⁷ | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
|---|---|---|---|---|---|---|---|
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
64 + 8 + 4 + 1 = 77, donc (01001101)₂ = (77)₁₀.
print(int('1101', 2)) print(int('01001101', 2))
Sortie attendue : 13 puis 77. int(chaîne, 2) interprète la chaîne comme un nombre écrit en base 2.
À toi, convertis à la main : 1₂, 10₂, 100₂, 1110₂, 101010₂.
1₂ = 1 · 10₂ = 2 · 100₂ = 4 · 1110₂ = 14 · 101010₂ = 42
→ Fiche d'exercices : exercices 4 à 7.
On effectue une succession de divisions euclidiennes par 2, jusqu'à obtenir un quotient nul. Le résultat est la juxtaposition des restes, lus du dernier au premier.
| Division | Quotient | Reste |
|---|---|---|
| 77 ÷ 2 | 38 | 1 |
| 38 ÷ 2 | 19 | 0 |
| 19 ÷ 2 | 9 | 1 |
| 9 ÷ 2 | 4 | 1 |
| 4 ÷ 2 | 2 | 0 |
| 2 ÷ 2 | 1 | 0 |
| 1 ÷ 2 | 0 | 1 |
Restes lus de bas en haut : 1001101, donc (77)₁₀ = (1001101)₂.
=.
n = 10 n = n - 1 # n vaut maintenant 9
if / elif / else — exécute un bloc selon une condition (bloc indenté de 4 espaces) :
if n == 0: print("zero") elif n > 0: print("positif") else: print("negatif")
while — répète tant qu'une condition est vraie. C'est celle utilisée dans ce chapitre, car on ne connaît pas à l'avance le nombre de divisions :
n = 13 while n > 0: print(n) n = n - 1 # affiche 13, 12, 11, ... jusqu'a 1
for — répète un nombre de fois connu à l'avance, souvent avec range() :
for i in range(5): print(i) # affiche 0, 1, 2, 3, 4
% et division entière // — les deux opérateurs au cœur de ce chapitre :
13 % 2 # reste de 13 / 2 -> 1 13 // 2 # quotient de 13 / 2 -> 6
[] liste vide, .append(x) ajoute à la fin, .reverse() inverse sur place :
chiffres = [] chiffres.append('1') chiffres.append('0') print(chiffres) # ['1', '0'] chiffres.reverse() print(chiffres) # ['0', '1']
''.join(liste) colle les éléments ensemble :
''.join(['1', '0', '1']) # '101'
def définit une fonction, return renvoie son résultat :
def double(x): return x * 2 print(double(5)) # 10
Avant d'écrire la fonction, vérifie que tu comprends bien ce que fait la boucle while : trace son exécution pour n = 13 (une ligne du tableau = un tour de boucle).
| Tour | n (avant) | n > 0 ? | reste = n % 2 | n (après n // 2) |
|---|---|---|---|---|
| 1 | 13 | Vrai | ? | ? |
| 2 | ? | Vrai | ? | ? |
| 3 | ? | Vrai | ? | ? |
| 4 | ? | Vrai | ? | ? |
| 5 | ? | ? | — | — |
| Tour | n (avant) | n > 0 ? | reste = n % 2 | n (après n // 2) |
|---|---|---|---|---|
| 1 | 13 | Vrai | 1 | 6 |
| 2 | 6 | Vrai | 0 | 3 |
| 3 | 3 | Vrai | 1 | 1 |
| 4 | 1 | Vrai | 1 | 0 |
| 5 | 0 | Faux | — | — |
Liste chiffres obtenue (dans l'ordre d'ajout) : 1, 0, 1, 1 → après chiffres.reverse() : 1, 1, 0, 1. Donc entier_vers_binaire(13) affiche 1101.
Le reste de n divisé par 2, c'est n % 2 (à ajouter avec .append()). Le quotient, c'est n // 2. Pour remettre les chiffres dans le bon ordre, une liste a une méthode .reverse().
def entier_vers_binaire(n): if n == 0: return '0' chiffres = [] while n > 0: chiffres.append(str(n % 2)) n = n // 2 chiffres.reverse() return ''.join(chiffres)
La base 16 a besoin de 16 symboles : les 10 chiffres 0 à 9, puis A, B, C, D, E, F pour 10 à 15.
Même principe que pour le binaire, avec des divisions successives par 16 :
| Division | Quotient | Reste |
|---|---|---|
| 335 ÷ 16 | 20 | 15 (=F) |
| 20 ÷ 16 | 1 | 4 |
| 1 ÷ 16 | 0 | 1 |
Donc (335)₁₀ = (14F)₁₆.
À toi : convertis 965 en base 16.
965 ÷ 16 = 60 reste 5 ; 60 ÷ 16 = 3 reste 12 (C) ; 3 ÷ 16 = 0 reste 3 → 965 = 3C5₁₆
→ Fiche d'exercices : exercices 12 et 13.
En base b, on a besoin de b symboles. Un nombre écrit (aₙ₋₁ ... a₁ a₀) en base b se lit comme une somme de puissances de b :
On effectue une succession de divisions euclidiennes par b, jusqu'à un quotient nul. Le résultat est la juxtaposition des restes, lus du dernier au premier (même méthode qu'en base 2 ou en base 16, avec b au lieu de 2 ou 16).
| Division | Quotient | Reste |
|---|---|---|
| 50 ÷ 3 | 16 | 2 |
| 16 ÷ 3 | 5 | 1 |
| 5 ÷ 3 | 1 | 2 |
| 1 ÷ 3 | 0 | 1 |
Donc (50)₁₀ = (1212)₃.
bⁿ valeurs, de 0 à bⁿ − 1. C'est la généralisation du cas b = 2 vu en partie 3 (2ⁿ valeurs, de 0 à 2ⁿ − 1).
On applique directement la formule ci-dessus : chaque chiffre est multiplié par la puissance de b correspondant à sa position, puis on additionne.
| 16² | 16¹ | 16⁰ |
|---|---|---|
| 256 | 16 | 1 |
| 7 | 2 | C |
7×256 + 2×16 + 12×1 = 1792 + 32 + 12 = 1836, donc (72C)₁₆ = (1836)₁₀ (rappel : C₁₆ = 12₁₀).
→ Fiche d'exercices : exercice 14.
Tout ce qu'on a vu se code aussi : divisions successives par b.
La structure est identique à entier_vers_binaire : seul le 2 devient b, à trois endroits.
def entier_vers_base(n, b): if n == 0: return '0' chiffres = [] while n > 0: chiffres.append(str(n % b)) n = n // b chiffres.reverse() return ''.join(chiffres)
Pour b = 16, un reste peut valoir jusqu'à 15 : il faut le traduire en symbole. La chaîne "0123456789ABCDEF" indexée par le reste donne directement le bon caractère.
Remplace str(n % b) par symboles[n % b] : ça pioche directement le bon caractère (chiffre ou lettre).
def entier_vers_base(n, b): symboles = "0123456789ABCDEF" if n == 0: return '0' chiffres = [] while n > 0: chiffres.append(symboles[n % b]) n = n // b chiffres.reverse() return ''.join(chiffres)
print(hex(335)) print(format(335, 'X')) print(int('14F', 16))
Sortie attendue : 0x14f, puis 14F, puis 335. hex() ajoute le préfixe 0x ; format(n, 'X') donne des majuscules.
Sur 4 bits, on représente exactement 2⁴ = 16 valeurs : chaque chiffre hexadécimal correspond donc exactement à un groupe de 4 bits.
| Décimal | Binaire | Hexadécimal |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
| Binaire | 0100 | 1101 |
|---|---|---|
| Décimal | 4 | 13 |
| Hexadécimal | 4 | D |
Donc (0100 1101)₂ = (4D)₁₆.
0b pour le binaire (0b1101), 0x pour l'hexadécimal (0x1F), et — bonus — 0o pour l'octal / base 8 (0o17).
n = 0b01001101 print(format(n, 'X')) print(format(0xB931, 'b'))
Sortie attendue : 4D puis 1011100100110001. 0b… et 0x… sont des écritures littérales reconnues directement par Python.
→ Fiche d'exercices : exercices 15 et 16.
3 exercices de difficulté croissante. Réfléchis avant de consulter la correction !
Convertis en binaire : 9, 20, 50. Convertis en décimal : 1010₂, 11111₂.
9 = 1001₂ · 20 = 10100₂ · 50 = 110010₂
1010₂ = 10 · 11111₂ = 31
Prédis puis exécute pour vérifier. Complète aussi la question sur 60 en binaire sur 8 bits.
format(45, '08b') → 00101101 · int('101010', 2) → 42
Et 60 = 00111100₂ (sur 8 bits).
Complète poids_binaire(n) (nombre de bits à 1) puis est_puissance_de_deux(n), sans utiliser bin() ni format().
entier_vers_binaire(n).count('1') compte directement les bits à 1. Une puissance de 2 s'écrit toujours avec un seul bit à 1.
def poids_binaire(n): return entier_vers_binaire(n).count('1') def est_puissance_de_deux(n): return n > 0 and poids_binaire(n) == 1
Coche une case par ligne — ta progression est enregistrée automatiquement sur cet appareil. Pour une notion « à revoir », reprends l'exemple guidé correspondant puis refais un exercice sans aide.
| Compétence | Seul | Avec aide | À revoir |
|---|---|---|---|
| Convertir un binaire en décimal (somme des puissances de 2 où il y a un 1) | |||
| Convertir un décimal en binaire (divisions successives par 2, lecture des restes) | |||
| Savoir combien de valeurs on code avec n bits (2ⁿ), et l'intervalle (0 à 2ⁿ−1) | |||
| Convertir décimal ↔ hexadécimal (divisions/puissances de 16, symboles A-F) | |||
| Convertir binaire ↔ hexadécimal par paquets de 4 bits | |||
| Généraliser à une base b quelconque (formule Σ aᵢ × bⁱ, divisions successives par b) | |||
| Reconnaître et utiliser les notations Python 0b, 0x, 0o | |||
| Distinguer bin()/format(n,'b') (avec/sans préfixe 0b) et int(chaîne, base) | |||
| Écrire une fonction Python de conversion sans bin() ni format() | |||
| Expliquer pourquoi représentation et information ne sont pas la même chose |
Mon prochain objectif :
k pèse 2^k, pas k.bin(n) (avec le préfixe 0b) et format(n, 'b') (sans préfixe).Entre un nombre dans une base, il se convertit automatiquement dans les autres — utile pour vérifier tes calculs à la main.
Modifie n'importe quel champ, les deux autres se mettent à jour automatiquement.
Banque de 52 questions. Choisissez le nombre de questions et lancez le tirage.