Ecritures des entiers☘
On considère le programme python suivant:
def de_caractere_vers_chiffre(caractere_chiffre):
if caractere_chiffre == '0': return 0
elif caractere_chiffre == '1': return 1
elif caractere_chiffre == '2': return 2
elif caractere_chiffre == '3': return 3
elif caractere_chiffre == '4': return 4
elif caractere_chiffre == '5': return 5
elif caractere_chiffre == '6': return 6
elif caractere_chiffre == '7': return 7
elif caractere_chiffre == '8': return 8
elif caractere_chiffre == '9': return 9
def de_ecritureb_vers_decimal(code_entier, base):
"""
base: entier >= 2 (pour le moment on supposera b < 10)
code_entier: chaîne de caractères ne contenant
que des symboles chiffres entre 0 et b-1
renvoie un entier
"""
s = 0
for chiffre in code_entier:
s = base*s + de_caractere_vers_chiffre(chiffre)
return s
Ce programme associe à une chaîne de caractères-chiffres un entier.
Cette association est en fait l'association que vous utilisez naturellement en écrivant les entiers.... Détails dans ce qui suit !
Base dix☘
Répondre aux questions suivantes à la main (sans faire tourner le programme sur machine).
Donner les valeurs obtenues avec les appels suivants:
>>> de_ecritureb_vers_decimal('4536', 10)
>>> de_ecritureb_vers_decimal('123', 10)
>>> de_ecritureb_vers_decimal('32', 10)
4536, lecture 1
Un premier déroulement du code.
Avec l'appel
>>> de_ecritureb_vers_decimal('4536', 10)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '4536'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 10. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '4' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 0 + 4 = 4. - la variable
chiffre
prend ensuite la valeur '5' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 4 + 5 = 40+5 = 45. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times\left(45\right) + 3 = 450 + 3 = 453. - la variable
chiffre
prend ensuite la valeur '6' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times\left(453\right) + 6 = 4530 + 6 = 4536.
- la variable
On obtient l'entier donné initialement par la chaîne de caractères.
4536, lecture 2
On lit à nouveau le déroulement du code mais sans effectuer les calculs intermédiaires. Cela permet de mettre en évidence les puissances de 10 successives.
Avec l'appel
>>> de_ecritureb_vers_decimal('4536', 10)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '4536'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 10. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '4' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 0 + 4 = 4. - la variable
chiffre
prend ensuite la valeur '5' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 4 + 5. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times\left(10\times 4 + 5\right) + 3. - la variable
chiffre
prend ensuite la valeur '6' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times\left[10\times\left(10\times 4 + 5\right) + 3\right] + 6.
- la variable
Cette dernière valeur est la valeur renvoyée. Développons l'expression pour mieux comprendre en commençant par le couple de parenthèses le plus interne:
On retrouve l'entier donné initialement. Ne pas effectuer les calculs intermédiaires permet ici de mettre en évidence que l'algorithme proposé lit le chiffre de droite comme le chiffre des unités (coefficient de 10^0), le chiffre suivant (en lecture de droite à gauche, ici 3) comme le chiffre des dizaines (coefficient de 10^1), le chiffre suivant (ici 5) comme le chiffre des centaines (coefficient de 10^2), et le suivant (ici 4) comme le chiffre des milliers (coefficient de 10^3).
123
Avec l'appel
>>> de_ecritureb_vers_decimal('123', 10)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '123'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 10. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '1' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 0 + 1 = 1. - la variable
chiffre
prend ensuite la valeur '2' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 1+ 2. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times\left(10\times 1 + 2\right) + 3.
- la variable
Cette dernière valeur est la valeur renvoyée. Développons l'expression:
32
Avec l'appel
>>> de_ecritureb_vers_decimal('32", 10)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '32'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 10. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 0 + 3 = 3. - la variable
chiffre
prend ensuite la valeur '2' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 10\times 3+ 2 = 32.
- la variable
Cette dernière valeur est la valeur renvoyée.
Important
Lorsque le paramètre base
désigne la valeur 10, le programme transforme donc une chaîne de "caractères-chiffres" (type str)
en l'entier (type int) correspondant.
L'effet est donc, dans ce cas, a priori identique à ce que l'on obtiendrait avec la fonction int
prédéfinie en python.
>>> int("123")
123
Base huit☘
Répondre de même aux questions suivantes à la main (sans faire tourner le programme sur machine).
On notera bien que les chaînes, lorsque la base est 8, ne contiennent que des chiffres entre 0 et 7 (ce n'est pas important pour le moment dans le déroulement du programme mais ce le sera pour comprendre l'écriture en base huit).
Donner les valeurs obtenues avec les appels suivants:
>>> de_ecritureb_vers_decimal('4536', 8)
>>> de_ecritureb_vers_decimal('123', 8)
>>> de_ecritureb_vers_decimal('32', 8)
4536
On lit à nouveau le déroulement du code sans effectuer les calculs intermédiaires. On constatera cette fois que ce sont des puissances de 8 qui apparaissent dans la somme finale.
Avec l'appel
>>> de_ecritureb_vers_decimal('4536', 8)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '4536'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 8. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '4' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 0 + 4 = 4. - la variable
chiffre
prend ensuite la valeur '5' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 4 + 5. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times\left(8\times 4 + 5\right) + 3. - la variable
chiffre
prend ensuite la valeur '6' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times\left[8\times\left(8\times 4 + 5\right) + 3\right] + 6.
- la variable
Cette dernière valeur est la valeur renvoyée. Développons l'expression pour mieux comprendre en commençant par le couple de parenthèses le plus interne:
123
Avec l'appel
>>> de_ecritureb_vers_decimal('123', 8)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '123'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 8. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '1' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 0 + 1 = 1. - la variable
chiffre
prend ensuite la valeur '2' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 1+ 2. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times\left(8\times 1 + 2\right) + 3.
- la variable
Cette dernière valeur est la valeur renvoyée. Développons l'expression:
32
Avec l'appel
>>> de_ecritureb_vers_decimal('32", 8)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '32'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 8. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 0 + 3 = 3. - la variable
chiffre
prend ensuite la valeur '2' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 8\times 3+ 2 = 26.
- la variable
Cette dernière valeur est la valeur renvoyée.
Important
Nous voyons ainsi que le code "123" peut représenter l'entier 83.
Nous écrirons 123_{\text{huit}} = 83_{\text{dix}}.
Nous dirons que 123 est l'écriture en base huit de l'entier écrit usuellement 83.
L'écriture usuelle des entiers est une écriture en base 10, appelée également écriture décimale.
Ainsi 4371_{\text{huit}} = 4 \times 8^3 + 3 \times 8^2 + 7 \times 8 + 1 tandis que 4371 = 4371_{\text{dix}} = 4 \times 10^3 + 3 \times 10^2 + 7 \times 10 + 1.
Remarque
La fonction prédéfinie int
dans le langage python permet de même d'obtenir à l'écran l'écriture en base dix
à partir d'une écriture en base 8:
>>> int("123", 8)
83
Important
En base huit, les seuls chiffres autorisés sont les chiffres de 0 à 7 (sinon, par exemple, 81_{\text{huit}} serait égal à 8\times 8 +1 c'est à dire à 1\times 8^2 + 0\times 8 + 1 et pourrait donc aussi s'écrire 101_{\text{huit}}, et on cherche à éliminer cette possibilité de multiples écritures dans une base donnée. Nous verrons aussi dans la suite que les chiffres sont tout simplement obtenus comme des restes dans une division par 8, donc compris entre 0 et 7).
Notre fonction de_caractere_vers_chiffre
, pour être plus correcte, devrait donc refuser les chiffres 8 et 9
lorsque la base est 8. C'est bien sûr le cas avec la fonction python int
:
>>> int("1287", 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 8: '1287'
Base cinq☘
Répondre de même aux questions suivantes à la main (sans faire tourner le programme sur machine).
En base cinq, les seuls chiffres autorisés sont 0, 1, 2, 3, 4.
- Donner la valeur obtenue avec l' appel suivant:
>>> de_ecritureb_vers_decimal('4312', 5)
4312
On lit à nouveau le déroulement du code sans effectuer les calculs intermédiaires. On constatera cette fois que ce sont des puissances de 5 qui apparaissent dans la somme finale.
Avec l'appel
>>> de_ecritureb_vers_decimal('4312', 5)
- une variable
code_entier
, locale à la fonction, est créée, et cette variable désigne la valeur de type str '4312'. - une variable
base
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 5. - une variable
s
, locale à la fonction, est créée, et cette variable désigne la valeur de type int 0. - On commence ensuite la boucle for:
- la variable
chiffre
prend la valeur '4' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 5\times 0 + 4 = 4. - la variable
chiffre
prend ensuite la valeur '3' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 5\times 4 + 3. - la variable
chiffre
prend ensuite la valeur '1' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 5\times\left(5\times 4 + 3\right) + 1. - la variable
chiffre
prend ensuite la valeur '2' puis la variables
prend la valeurbase*s + de_caractere_vers_chiffre(chiffre)
, soit 5\times\left[5\times\left(5\times 4 + 3\right) + 1\right] + 2.
- la variable
Cette dernière valeur est la valeur renvoyée. Développons l'expression pour mieux comprendre en commençant par le couple de parenthèses le plus interne:
- Donner l'écriture en base dix de 123_{\text{cinq}}.
123
Avec l'appel
>>> de_ecritureb_vers_decimal('123', 5)
38
Avec int
:
>>> int("123", 5)
38
et à la main:
123_{\text{cinq}} = 1\times 5^2 + 2 \times 5 + 3 = 38.
- Donner l'écriture en base dix de 32_{\text{cinq}}.
32
Avec le programme:
>>> de_ecritureb_vers_decimal('32", 5)
17
Avec la fonction int
de python:
>>> int("32", 5)
17
et à la main:
32_{\text{cinq}} = 3 \times 5 + 2 = 17.
Base deux☘
En base deux, les seuls chiffres autorisés sont les chiffres 0 et 1.
Donner l'écriture en base dix des entiers suivants:
- a = 101_{\text{deux}}
- b = 10_{\text{deux}}
- c = 1110_{\text{deux}}
101
Avec notre fonction ou avec int
:
>>> de_ecritureb_vers_decimal("101",2)
5
>>> int("101", 2)
5
Et à la main:
a = 101_{\text{deux}} = 1\times 2^2 + 0 \times 2 + 1 = 5
10
Avec notre fonction ou avec int
:
>>> de_ecritureb_vers_decimal("10",2)
2
>>> int("10", 2)
2
Et à la main:
b = 10_{\text{deux}} = 1\times 2 + 0 = 2.
1110
Avec notre fonction ou avec int
:
>>> de_ecritureb_vers_decimal("1110", 2)
14
>>> int("1110", 2)
14
Et à la main:
c = 1110_{\text{deux}} = 1\times 2^3 + 1\times 2^2 + 1\times 2 + 0 = 14.
Exercice☘
Nous avons signalé qu'en base b (on suppose ici 2\leqslant b \leqslant 9), les chiffres autorisés sont les chiffres de 0 à b-1.
Ajoutez une instruction assert
dans le script précédent afin que l'utilisateur soit prévenu lorsqu'il utilise un symbole non autorisé.
Solution
Un code possible:
def de_caractere_vers_chiffre(caractere_chiffre):
if caractere_chiffre == '0': return 0
elif caractere_chiffre == '1': return 1
elif caractere_chiffre == '2': return 2
elif caractere_chiffre == '3': return 3
elif caractere_chiffre == '4': return 4
elif caractere_chiffre == '5': return 5
elif caractere_chiffre == '6': return 6
elif caractere_chiffre == '7': return 7
elif caractere_chiffre == '8': return 8
elif caractere_chiffre == '9': return 9
def de_ecritureb_vers_decimal(code_entier, base):
"""
base: entier >= 2 (pour le moment on supposera b < 10)
code_entier: chaîne de caractères ne contenant
que des symboles chiffres entre 0 et b-1
renvoie un entier
"""
s = 0
for chiffre in code_entier:
assert de_caractere_vers_chiffre(chiffre) in range(0, base), \
f"Attention, en base {base}, le symbole {chiffre} n'est pas autorisé."
s = base*s + de_caractere_vers_chiffre(chiffre)
return s