Exercice (6,5 points) — dans l’esprit des sessions de contrôle 2018 et 2022, section Sciences de l’informatique
On se propose d’écrire un programme qui affiche l’écriture, dans une base B (2 ≤ B ≤ 16), d’un entier naturel N (50 ≤ N ≤ 30000), puis vérifie ce résultat par la conversion inverse vers le décimal. Les chiffres de 10 à 15 sont notés "A" à "F", comme en hexadécimal.
Principe : on effectue des divisions euclidiennes successives par B (on divise N par B, puis le quotient obtenu par B, etc.) jusqu’à obtenir un quotient nul ; les restes sont rangés au fur et à mesure dans un tableau R, puis on renverse ce tableau et on concatène les caractères qui correspondent à ses valeurs.
Exemple : pour N = 2026 et B = 16 : 2026 = 126 × 16 + 10 ; 126 = 7 × 16 + 14 ; 7 = 0 × 16 + 7. Après rangement, R = [10, 14, 7] ; après renversement, R = [7, 14, 10] ; l’écriture obtenue est "7EA". Vérification : (7 × 16 + 14) × 16 + 10 = 2026.
Travail demandé :
- Justifier qu’un tableau R de 15 entiers suffit pour ranger tous les restes, quelle que soit la base B.
- Écrire l’algorithme d’une procédure Saisir(P, Binf, Bsup) qui permet de saisir un entier P tel que Binf ≤ P ≤ Bsup.
- Écrire l’algorithme d’une procédure Restes(N, B, R, nb) qui range dans R les restes successifs des divisions par B jusqu’à un quotient nul et calcule leur nombre nb.
- Écrire l’algorithme d’une procédure Inverser(R, nb) qui renverse les nb premières valeurs de R par permutations symétriques (R[0] avec R[nb − 1], R[1] avec R[nb − 2], etc.). Justifier la valeur finale du compteur.
- Écrire l’algorithme d’une fonction Chiffre(c) qui retourne le caractère correspondant à un entier c (0 ≤ c ≤ 15). Exemples : Chiffre(9) retourne "9", Chiffre(14) retourne "E".
- En faisant appel à Inverser et à Chiffre, écrire l’algorithme d’une fonction Ecriture(R, nb) qui retourne la chaîne représentant N dans la base B.
- Écrire l’algorithme d’une fonction Valeur(ch, B) qui retourne la valeur décimale d’une chaîne ch écrite en base B, par le schéma de Horner (v ← v × B + chiffre, de gauche à droite).
- En faisant appel uniquement aux modules précédents, écrire l’algorithme du programme principal qui saisit N et B, affiche l’écriture de N en base B, puis affiche « Vérification réussie » si la conversion inverse redonne N.
N.B. : dresser les tableaux de déclaration des nouveaux types et des objets.
Voir la correction commentéeAprès avoir posé votre démarche
1. Idée : le nombre de restes est le nombre de chiffres de N en base B, maximal pour B = 2. 2¹⁴ = 16384 ≤ 30000 < 2¹⁵ = 32768 : en binaire, N s’écrit sur au plus 15 chiffres (30000 = ), et sur moins de chiffres dans toute base plus grande. .
2.
Procédure Saisir (@P : Entier,
Binf, Bsup : Entier)
DEBUT
Répéter
Ecrire("Donner un entier : ")
Lire(P)
Jusqu'à (P ≥ Binf) Et (P ≤ Bsup)
FIN3. Idée : Répéter, car il y a toujours au moins une division ; nb sert d’indice de la prochaine case avant d’être incrémenté.
Procédure Restes (N, B : Entier, @R : TAB,
@nb : Entier)
DEBUT
nb ← 0
Répéter
R[nb] ← N Mod B
nb ← nb + 1
N ← N Div B
Jusqu'à N = 0
FINPour 2026 et 16 : R[0] = 10 (N devient 126), R[1] = 14 (N devient 7), R[2] = 7 (N devient 0) ; nb = 3.
4. Idée : chaque échange place deux valeurs à leur rang définitif ; il faut nb Div 2 échanges. Aller plus loin referait les échanges déjà faits.
Procédure Inverser (@R : TAB, nb : Entier)
DEBUT
Pour i de 0 à (nb Div 2) - 1 Faire
x ← R[i]
R[i] ← R[nb - 1 - i]
R[nb - 1 - i] ← x
Fin Pour
FINTDOL : i, x — Type/Nature : Entier — compteur, variable d’échange. Pour nb impair (N = 2026, B = 5 : R = [1, 0, 1, 1, 3]), la valeur du milieu ne bouge pas et l’on obtient [3, 1, 1, 0, 1]. Avec la borne nb Div 2 au lieu de (nb Div 2) − 1, un tableau de 4 valeurs [1, 2, 3, 4] deviendrait [4, 2, 3, 1] : la paire du milieu serait échangée deux fois.
5. Idée : les codes ASCII de "0" à "9", puis de "A" à "F", sont consécutifs.
Fonction Chiffre (c : Entier) : Caractère
DEBUT
Si c < 10 Alors
Retourner Chr(Ord("0") + c)
Sinon
Retourner Chr(Ord("A") + c - 10)
FinSi
FIN6.
Fonction Ecriture (R : TAB,
nb : Entier) : Chaîne
DEBUT
Inverser(R, nb)
ch ← ""
Pour i de 0 à nb - 1 Faire
ch ← ch + Chiffre(R[i])
Fin Pour
Retourner ch
FINTDOL : ch — Chaîne — écriture en construction ; i — Entier ; Inverser — Procédure ; Chiffre — Fonction. Sur l’exemple : "7", puis "7E", puis "7EA".
7. Idée : chaque nouveau chiffre décale la valeur déjà lue d’un rang (× B) avant d’être ajouté.
Fonction Valeur (ch : Chaîne,
B : Entier) : Entier
DEBUT
v ← 0
Pour i de 0 à Long(ch) - 1 Faire
Si ch[i] ≤ "9" Alors
c ← Ord(ch[i]) - Ord("0")
Sinon
c ← Ord(ch[i]) - Ord("A") + 10
FinSi
v ← v * B + c
Fin Pour
Retourner v
FINTDOL : v, c, i — Type/Nature : Entier — valeur lue, chiffre courant, position. Pour "7EA" : v = 7, puis 7 × 16 + 14 = 126, puis 126 × 16 + 10 = .
8.
Algorithme Conversion_B
DEBUT
Saisir(N, 50, 30000)
Saisir(B, 2, 16)
Restes(N, B, R, nb)
ch ← Ecriture(R, nb)
Ecrire(N, " = (", ch, ") base ", B)
Si Valeur(ch, B) = N Alors
Ecrire("Vérification réussie")
FinSi
FINTableau de déclaration des nouveaux types : TAB = Tableau de 15 Entiers.
Tableau de déclaration des objets globaux :
N,B,nb— Type/Nature : Entier — nombre, base, nombre de restesR— Type/Nature : TAB — restes successifsch— Type/Nature : Chaîne — écriture de N en base BSaisir,Restes— Type/Nature : Procédure ;Ecriture,Valeur— Type/Nature : Fonction
Pour N = 2026 : B = 16 affiche « 2026 = (7EA) base 16 », B = 5 affiche « 2026 = (31101) base 5 », et la vérification réussit dans les deux cas.