Écrire une fonction racine entiere(n) renvoyant ⌊√n⌋ sans utiliser…
Exercice de TD · niveau 3 (difficile) · NSI (première), chapitre 3 — Langages et programmation · Spécifier : prototype, préconditions, postconditions
Énoncé
Écrire une fonction racine_entiere(n) renvoyant sans utiliser math.sqrt, avec précondition et postcondition exprimées par des assertions. Indication pour la postcondition : .
Corrigé
def racine_entiere(n):
"""Partie entiere de la racine carree de n.
Precondition : n est un entier >= 0.
Postcondition : r*r <= n < (r+1)*(r+1).
"""
assert n >= 0, "n doit etre positif ou nul"
r = 0
while (r + 1) * (r + 1) <= n:
r = r + 1
assert r * r <= n < (r + 1) * (r + 1)
return r
Pourquoi la postcondition est la bonne. Elle ne mentionne ni racine carrée ni flottant : elle est écrite entièrement avec des entiers et des multiplications. C'est ce qui la rend vérifiable sans risque — l'avertissement du cours sur les postconditions flottantes ne s'applique pas ici. Et elle caractérise de façon unique : deux entiers distincts ne peuvent pas vérifier tous deux cet encadrement.
Invariant et terminaison. L'invariant est r * r <= n : il est vrai au départ () et le corps ne s'exécute que si , ce qui le préserve. Le variant est , entier positif qui décroît strictement : la boucle s'arrête.
La vérification.
for n in range(0, 10001):
r = racine_entiere(n)
assert r * r <= n < (r + 1) * (r + 1)
Les cas passent. Contrôles : , , et puisque .
Pourquoi éviter math.sqrt : sur de grands entiers, la racine flottante peut tomber juste en dessous d'un entier exact, et int(math.sqrt(n)) rend alors . La version entière n'a pas ce défaut, parce qu'elle ne quitte jamais .
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.