Adloun

É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 &lt;= 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.