La méthode de Héron Grand Oral · mathématiques, NSI, HGGSP Un support de connaissances pour construire sa propre question

← Tous les textes du Grand Oral

MathsNSIHGGSP

Comment calculer $\sqrt{720}$ sans calculatrice ? Il y a près de deux mille ans, Héron d'Alexandrie donne une recette qui tient en trois opérations : diviser, ajouter, prendre la moitié. Répétée, elle fournit des valeurs de plus en plus précises, et elle est si efficace que le nombre de chiffres exacts double à chaque étape. Les scribes de Babylone semblent avoir connu une méthode voisine bien avant Héron, et la même idée, sous le nom de méthode de Newton, tourne encore aujourd'hui dans les calculatrices, les processeurs et même dans un célèbre jeu vidéo.

Ce texte reprend le passage de Héron, explique pourquoi la recette fonctionne (avec des rectangles, puis avec une construction géométrique), puis démontre tout avec les outils de terminale : suites définies par récurrence, raisonnement par récurrence, suites monotones et bornées, limite et continuité, dérivée et tangente, algorithmique. Il ne propose pas de Grand Oral tout fait : à chacun d'y choisir une direction et d'y construire sa question.

Sommaire
  1. Le texte de Héron : la racine de $720$
  2. Pourquoi ça marche : des rectangles qui deviennent des carrés
  3. Une construction à la règle et au compas
  4. L'étude de la suite
  5. Le nombre de chiffres exacts double
  6. Babylone : la tablette YBC 7289
  7. La méthode de Héron est une méthode de Newton
  8. Les racines carrées dans les machines
  9. Des directions pour construire sa question
Le texte de Héron : la racine de $720$ Héron d'Alexandrie

Héron vit à Alexandrie, en Égypte romaine, probablement au Ier siècle de notre ère ; on ne sait presque rien de sa vie. Il enseigne et écrit des traités pratiques : machines à vapeur (l'éolipile), automates de théâtre, instruments de visée pour l'arpentage, et un traité de mesure des surfaces et des volumes, les Metrica, dont le manuscrit n'a été retrouvé, à Constantinople, qu'à la fin du XIXe siècle. C'est là que figure la célèbre formule de Héron, qui donne l'aire d'un triangle à partir de ses trois côtés. Pour un triangle de côtés $7$, $8$ et $9$, elle conduit à $\sqrt{720}$, et Héron explique comment en obtenir une valeur approchée.

Le passage

Voici le passage, dans la traduction donnée par Jean-Luc Chabert dans Histoires d'algorithmes :

Puisque $720$ n'a pas de côté rationnel, nous extrairons le côté avec une très petite différence de la façon suivante. Comme le premier nombre carré plus grand que $720$ est $729$ qui a pour côté $27$, divise $720$ par $27$ ; cela fait $26$ et $\frac{2}{3}$ ; ajoute $27$, cela fait $53$ $\frac{2}{3}$ ; prends-en la moitié, cela fait $26$ $\frac{1}{2}$ $\frac{1}{3}$. Car $26$ $\frac{1}{2}$ $\frac{1}{3}$ multiplié par lui-même donne $720$ $\frac{1}{36}$, de sorte que la différence (sur les carrés) est $\frac{1}{36}$. Si nous voulons rendre cette différence inférieure encore à $\frac{1}{36}$, nous mettrons $720$ $\frac{1}{36}$ trouvé tout à l'heure à la place de $729$ et en procédant de la même façon…

Le calcul, phrase par phrase

« $720$ n'a pas de côté rationnel » : un carré d'aire $720$ a pour côté $\sqrt{720}$, qui n'est pas une fraction. On va donc en chercher une valeur approchée. Héron écrit les fractions comme les Égyptiens, en sommes de fractions de numérateur $1$ : « $26$ $\frac{1}{2}$ $\frac{1}{3}$ » signifie $26 + \frac{1}{2} + \frac{1}{3} = 26 + \frac{5}{6}$.

  • On part de $27$, car $27^2 = 729$ est le premier carré au-dessus de $720$.
  • On divise : $\dfrac{720}{27} = 26 + \dfrac{2}{3}$.
  • On ajoute $27$ : $26 + \dfrac{2}{3} + 27 = 53 + \dfrac{2}{3}$.
  • On prend la moitié : $\dfrac{1}{2}\left(53 + \dfrac{2}{3}\right) = 26 + \dfrac{5}{6}$.

Héron vérifie ensuite son résultat en l'élevant au carré :

$$\left(26 + \frac{5}{6}\right)^2 = 26^2 + 2 \times 26 \times \frac{5}{6} + \frac{25}{36},$$

donc

$$\begin{aligned} \left(26 + \frac{5}{6}\right)^2 &= 676 + \frac{130}{3} + \frac{25}{36} \\ &= 720 + \frac{1}{36}. \end{aligned}$$

Le carré de côté $26 + \frac{5}{6} \approx 26{,}8333$ a donc une aire qui ne dépasse $720$ que de $\frac{1}{36}$. En effet, $\sqrt{720} \approx 26{,}832\,816$ : en une seule étape, on est passé d'une erreur d'environ $0{,}17$ à une erreur d'environ $0{,}000\,5$.

La dernière phrase est la plus importante : pour faire mieux, on recommence avec la valeur obtenue à la place de $27$. En langage moderne, pour approcher $\sqrt{a}$, on part d'une valeur $u_0$ et l'on calcule

$$u_{n+1} = \frac{1}{2}\left(u_n + \frac{a}{u_n}\right).$$

C'est un algorithme : une suite d'opérations simples, répétée autant de fois que nécessaire. C'est aussi une suite définie par récurrence, et toute la suite du texte consiste à comprendre pourquoi elle tend vers $\sqrt{a}$, et à quelle vitesse.

Pourquoi ça marche : des rectangles qui deviennent des carrés

Chercher $\sqrt{a}$, c'est chercher le côté d'un carré d'aire $a$. Partons d'un rectangle d'aire $a$ dont un côté mesure $u$ : l'autre côté mesure alors $\dfrac{a}{u}$.

Pour $\sqrt{720}$, le premier rectangle mesure $27$ sur $26{,}67$ ; le suivant mesure $26{,}833\,3$ sur $26{,}832\,3$ : c'est presque un carré. La figure montre le même phénomène pour un nombre $a$ entre $2$ et $20$, en partant, comme Héron, du premier entier dont le carré dépasse $a$.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var petit = {fontSize: 11, useKatex: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false}; board.create('segment', [[0, 0], [5.8, 0]], ax); board.create('segment', [[0, 0], [0, 5.3]], ax); for (var t = 1; t <= 5; t++) { board.create('segment', [[t, 0], [t, -0.08]], ax); board.create('text', [t - 0.07, -0.3, String(t)], petit); board.create('segment', [[0, t], [-0.08, t]], ax); board.create('text', [-0.35, t, String(t)], petit); } var sa = board.create('slider', [[0.3, -0.75], [2.3, -0.75], [2, 10, 20]], {withLabel: false, snapWidth: 1}); var sk = board.create('slider', [[3.3, -0.75], [5.3, -0.75], [0, 0, 4]], {withLabel: false, snapWidth: 1}); function nb(x, d) { return x.toFixed(d).replace('.', ','); } function A() { return Math.round(sa.Value()); } function U() { var a = A(), u = Math.ceil(Math.sqrt(a) - 1e-12), k; if (u * u === a) { u = u + 1; } for (k = 0; k < Math.round(sk.Value()); k++) { u = (u + a / u) / 2; } return u; } var rect = board.create('polygon', [[0, 0], [function () { return U(); }, 0], [function () { return U(); }, function () { return A() / U(); }], [0, function () { return A() / U(); }]], {fillColor: '#1565c0', fillOpacity: 0.18, highlight: false, vertices: {visible: false}, borders: {strokeColor: '#1565c0', strokeWidth: 2, highlight: false}}); var car = board.create('polygon', [[0, 0], [function () { return Math.sqrt(A()); }, 0], [function () { return Math.sqrt(A()); }, function () { return Math.sqrt(A()); }], [0, function () { return Math.sqrt(A()); }]], {fillOpacity: 0, highlight: false, vertices: {visible: false}, borders: {strokeColor: '#c62828', strokeWidth: 1.5, dash: 2, highlight: false}}); board.create('text', [0.3, -1.05, function () { return 'a = ' + A(); }], opt); board.create('text', [3.3, -1.05, function () { return 'étape n = ' + Math.round(sk.Value()); }], opt); board.create('text', [0.15, 6.25, function () { return 'côtés : ' + nb(U(), 5) + ' et ' + nb(A() / U(), 5); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('text', [0.15, 5.75, function () { return 'carré cherché : √a ≈ ' + nb(Math.sqrt(A()), 5); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#c62828'}); En bleu, le rectangle d'aire $a$ obtenu à l'étape $n$ ; en pointillés rouges, le carré d'aire $a$ que l'on cherche. Le premier curseur règle $a$, le second le nombre d'étapes. Dès l'étape $2$ ou $3$, le rectangle et le carré ne se distinguent plus à l'œil.

Cette image explique pourquoi la méthode marche, mais elle ne prouve pas que les rectangles deviennent des carrés, ni à quelle vitesse. C'est l'objet des sections suivantes.

Une construction à la règle et au compas

À l'époque de Héron, et encore pendant des siècles, un calcul se justifie par une construction géométrique. Jean Dieudonné, dans Pour l'honneur de l'esprit humain, propose une construction qui donne exactement le nombre de Héron. La voici, démontrée avec le cours de collège et de lycée.

La figure

On part d'un carré $ABCD$ d'aire $a$, donc de côté $\sqrt{a}$. On prolonge les côtés $[AD]$ et $[BC]$ pour obtenir un rectangle $ABEF$ dont le côté $[AF]$ mesure un nombre $r > \sqrt{a}$ (une valeur approchée par excès de $\sqrt{a}$, comme $27$ pour $\sqrt{720}$). On trace la médiatrice du segment $[AE]$ : elle coupe la droite $(AF)$ en un point $J$. On complète le rectangle $ABJ'J$. On va démontrer que

$$AJ = \frac{1}{2}\left(r + \frac{a}{r}\right).$$ var opt = {fontSize: 13, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var lab = {fontSize: 13, useKatex: false, parse: false, fixed: true, highlight: false}; var s = 2; var sr = board.create('slider', [[-0.8, -0.85], [1.8, -0.85], [2.3, 3.2, 4.5]], {withLabel: false}); function R() { return sr.Value(); } function Jy() { return (R() + s * s / R()) / 2; } board.create('polygon', [[0, 0], [s, 0], [s, s], [0, s]], {fillColor: '#c62828', fillOpacity: 0.12, highlight: false, vertices: {visible: false}, borders: {strokeColor: '#c62828', strokeWidth: 1.5, highlight: false}}); board.create('polygon', [[0, 0], [s, 0], [s, function () { return R(); }], [0, function () { return R(); }]], {fillOpacity: 0, highlight: false, vertices: {visible: false}, borders: {strokeColor: '#455a64', strokeWidth: 1.5, highlight: false}}); board.create('polygon', [[0, 0], [s, 0], [s, function () { return Jy(); }], [0, function () { return Jy(); }]], {fillColor: '#1565c0', fillOpacity: 0.2, highlight: false, vertices: {visible: false}, borders: {strokeColor: '#1565c0', strokeWidth: 2, highlight: false}}); var A = board.create('point', [0, 0], {visible: false, fixed: true}); var E = board.create('point', [s, function () { return R(); }], {visible: false, fixed: true}); board.create('segment', [A, E], {strokeColor: '#455a64', strokeWidth: 1, dash: 2, highlight: false}); var M = board.create('point', [s / 2, function () { return R() / 2; }], {visible: false, fixed: true}); var M2 = board.create('point', [function () { return s / 2 - R(); }, function () { return R() / 2 + s; }], {visible: false, fixed: true}); board.create('line', [M, M2], {strokeColor: '#2e7d32', strokeWidth: 1.5, highlight: false}); var K = board.create('point', [0, function () { return R() + s * s / R(); }], {visible: false, fixed: true}); board.create('segment', [E, K], {strokeColor: '#2e7d32', strokeWidth: 1, dash: 2, highlight: false}); board.create('segment', [[0, function () { return R(); }], K], {strokeColor: '#455a64', strokeWidth: 1, highlight: false}); var pts = [[0, 0, 'A', -0.32, -0.12], [s, 0, 'B', 0.1, -0.12], [s, s, 'C', 0.1, -0.3], [0, s, 'D', -0.33, -0.05]]; pts.forEach(function (p) { board.create('point', [p[0], p[1]], {size: 2, name: '', fixed: true, color: '#263238', highlight: false}); board.create('text', [p[0] + p[3], p[1] + p[4], p[2]], lab); }); board.create('point', [0, function () { return R(); }], {size: 2, name: '', fixed: true, color: '#263238', highlight: false}); board.create('text', [0.1, function () { return R() + 0.25; }, 'F'], lab); board.create('point', [s, function () { return R(); }], {size: 2, name: '', fixed: true, color: '#263238', highlight: false}); board.create('text', [s + 0.1, function () { return R() + 0.02; }, 'E'], lab); board.create('point', [0, function () { return Jy(); }], {size: 3, name: '', fixed: true, color: '#1565c0', highlight: false}); board.create('text', [0.1, function () { return Jy() - 0.5; }, 'J'], {fontSize: 13, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('point', [s, function () { return Jy(); }], {size: 2, name: '', fixed: true, color: '#1565c0', highlight: false}); board.create('text', [s + 0.1, function () { return Jy() + 0.08; }, "J'"], {fontSize: 13, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('point', [0, function () { return R() + s * s / R(); }], {size: 2, name: '', fixed: true, color: '#2e7d32', highlight: false}); board.create('text', [-0.33, function () { return R() + s * s / R(); }, 'K'], {fontSize: 13, useKatex: false, parse: false, fixed: true, highlight: false, color: '#2e7d32'}); function nb(x, d) { return x.toFixed(d).replace('.', ','); } board.create('text', [-0.8, -1.25, function () { return 'r = ' + nb(R(), 2); }], opt); board.create('text', [0.6, -1.25, function () { return 'AJ = ' + nb(Jy(), 3) + ' (√a = 2)'; }], {fontSize: 13, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); Le carré rouge $ABCD$ a pour côté $\sqrt{a} = 2$. Le curseur règle $r = AF$. La médiatrice verte de $[AE]$ coupe $(AF)$ en $J$ ; le rectangle bleu $ABJ'J$ est le rectangle suivant de Héron, plus proche du carré que $ABEF$.
Le point $J$ est sur le segment $[DF]$

Étape 1. La médiatrice de $[AE]$ partage le plan en deux régions : les points plus proches de $A$ que de $E$, et les points plus proches de $E$ que de $A$.

Étape 2. On a $FA = FD + DA$ et $DA = FE$, donc $FA = FD + FE > FE$ : le point $F$ est plus proche de $E$ que de $A$.

Étape 3. Le triangle $DEF$ est rectangle en $F$, donc son hypoténuse vérifie $DE > FE = DA$ : le point $D$ est plus proche de $A$ que de $E$.

Étape 4. Les points $D$ et $F$ sont donc de part et d'autre de la médiatrice : elle coupe le segment $[DF]$ en un point, qui est $J$.

$AJ = \frac{1}{2}\left(r + \frac{a}{r}\right)$

Étape 1. On trace la parallèle à la médiatrice passant par $E$ ; elle coupe la droite $(AD)$ en $K$. La médiatrice passe par le milieu de $[AE]$ et elle est parallèle à $(EK)$ : d'après le théorème de Thalès (ou des milieux) dans le triangle $AEK$, elle coupe $[AK]$ en son milieu. Donc $J$ est le milieu de $[AK]$ et $AJ = \frac{1}{2}AK$.

Étape 2. La médiatrice est perpendiculaire à $(AE)$, donc $(EK)$ aussi : le triangle $AEK$ est rectangle en $E$, et $[EF]$ est sa hauteur issue de $E$. Dans un triangle rectangle, la hauteur vérifie $EF^2 = FA \times FK$ (démontré dans l'encadré ci-dessous).

Étape 3. Or $EF = \sqrt{a}$ et $FA = r$, donc $a = r \times FK$, soit $FK = \dfrac{a}{r}$.

Étape 4. Enfin $AK = AF + FK = r + \dfrac{a}{r}$, et donc $AJ = \dfrac{1}{2}\left(r + \dfrac{a}{r}\right)$.

La hauteur d'un triangle rectangle

Soit $ABC$ un triangle rectangle en $A$ et $H$ le pied de la hauteur issue de $A$. Alors $AH^2 = HB \times HC$.

Par les triangles semblables. Les angles $\widehat{HBA}$ et $\widehat{HAC}$ sont égaux (tous deux complémentaires de $\widehat{HAB}$), et les triangles $HBA$ et $HAC$ sont rectangles en $H$ : ils sont semblables. Leurs côtés sont proportionnels, donc $\dfrac{HB}{HA} = \dfrac{HA}{HC}$, d'où $HA^2 = HB \times HC$.

Par le produit scalaire. Comme $(AH)$ est perpendiculaire à $(BC)$, on a

$$\begin{aligned} &\overrightarrow{AB}\cdot\overrightarrow{AC} \\ &= \left(\overrightarrow{AH} + \overrightarrow{HB}\right)\cdot\left(\overrightarrow{AH} + \overrightarrow{HC}\right), \end{aligned}$$

donc, en développant et en utilisant $\overrightarrow{AH}\cdot\overrightarrow{HB} = \overrightarrow{AH}\cdot\overrightarrow{HC} = 0$ :

$$\overrightarrow{AB}\cdot\overrightarrow{AC} = AH^2 + \overrightarrow{HB}\cdot\overrightarrow{HC}.$$

Le premier membre est nul (angle droit en $A$), et $\overrightarrow{HB}\cdot\overrightarrow{HC} = -HB \times HC$ car les deux vecteurs sont de sens contraires. Donc $AH^2 = HB \times HC$.

La construction dit même un peu plus. Comme $J$ est sur la médiatrice, $JA = JE$, et l'inégalité triangulaire donne $JE < JF + FE$, c'est-à-dire $JD + DA < JF + FE$, donc $JD < JF$ : le point $J$ est plus près de $D$ que de $F$. L'excédent d'aire (le rectangle au-dessus du carré) est donc plus que divisé par deux à chaque étape : il tend vers $0$, et le côté $AJ$ tend vers $\sqrt{a}$. La section suivante montre que la réalité est bien meilleure encore.

L'étude de la suite

Soit $a$ un réel strictement positif et $u_0$ un réel strictement positif quelconque. On définit la suite $(u_n)$ par

$$u_{n+1} = \frac{1}{2}\left(u_n + \frac{a}{u_n}\right),$$

c'est-à-dire $u_{n+1} = f(u_n)$ avec $f(x) = \dfrac{1}{2}\left(x + \dfrac{a}{x}\right)$ sur $]0 ; +\infty[$.

La suite est bien définie et strictement positive

Par récurrence. Initialisation : $u_0 > 0$ par hypothèse. Hérédité : si $u_n > 0$, alors $\frac{a}{u_n} > 0$ et $u_{n+1}$, moitié d'une somme de deux nombres strictement positifs, est strictement positif. Conclusion : pour tout entier $n$, $u_n > 0$ ; en particulier on ne divise jamais par $0$.

L'égalité clé : $u_{n+1} - \sqrt{a} = \dfrac{(u_n - \sqrt{a})^2}{2u_n}$

Pour tout entier $n$, on met au même dénominateur :

$$u_{n+1} - \sqrt{a} = \frac{u_n^2 + a - 2u_n\sqrt{a}}{2u_n}.$$

Le numérateur est une identité remarquable, puisque $a = (\sqrt{a})^2$ :

$$u_{n+1} - \sqrt{a} = \frac{(u_n - \sqrt{a})^2}{2u_n}.$$

Cette égalité contient presque tout. Un carré est positif et $u_n > 0$, donc $u_{n+1} \geqslant \sqrt{a}$ pour tout $n$ : à partir du rang $1$, tous les termes sont supérieurs ou égaux à $\sqrt{a}$, quel que soit le point de départ. Si l'on part d'une valeur trop petite, la première étape la fait passer au-dessus.

On peut aussi le voir par une étude de fonction. Sur $]0 ; +\infty[$,

$$f'(x) = \frac{1}{2}\left(1 - \frac{a}{x^2}\right) = \frac{x^2 - a}{2x^2},$$

qui est du signe de $x - \sqrt{a}$ : $f$ est décroissante sur $]0 ; \sqrt{a}]$, croissante sur $[\sqrt{a} ; +\infty[$, et son minimum vaut $f(\sqrt{a}) = \sqrt{a}$. Donc $f(x) \geqslant \sqrt{a}$ pour tout $x > 0$.

À partir du rang $1$, la suite est décroissante

Pour tout $n \geqslant 1$,

$$\begin{aligned} u_{n+1} - u_n &= \frac{1}{2}\left(\frac{a}{u_n} - u_n\right) \\ &= \frac{a - u_n^2}{2u_n}. \end{aligned}$$

Comme $u_n \geqslant \sqrt{a} > 0$ et que la fonction carré est croissante sur $[0 ; +\infty[$, on a $u_n^2 \geqslant a$, donc $u_{n+1} - u_n \leqslant 0$.

La suite converge vers $\sqrt{a}$

Étape 1. À partir du rang $1$, la suite est décroissante et minorée par $\sqrt{a}$ : d'après le théorème de convergence monotone, elle converge vers une limite $\ell$ telle que $\ell \geqslant \sqrt{a} > 0$.

Étape 2. La fonction $f$ est continue en $\ell$, donc en passant à la limite dans $u_{n+1} = f(u_n)$, on obtient $\ell = f(\ell)$ :

$$\begin{aligned} \ell = \frac{1}{2}\left(\ell + \frac{a}{\ell}\right) &\iff 2\ell = \ell + \frac{a}{\ell} \\ &\iff \ell^2 = a. \end{aligned}$$

Étape 3. Comme $\ell > 0$, on conclut $\ell = \sqrt{a}$.

Le nombre de chiffres exacts double L'exemple de Héron, poursuivi

Avant de démontrer, regardons. Avec $a = 720$ et $u_0 = 27$, voici les premiers termes, comparés à $\sqrt{720} \approx 26{,}832\,815\,729\,997$.

$n$$u_n$$u_n - \sqrt{720}$
$0$$27$$0{,}167$
$1$$26{,}833\,333\,333$$5{,}2 \times 10^{-4}$
$2$$26{,}832\,815\,735$$5{,}0 \times 10^{-9}$
$3$$26{,}832\,815\,730$environ $5 \times 10^{-19}$

L'erreur passe de l'ordre de $10^{-1}$ à $10^{-4}$, puis $10^{-9}$, puis $10^{-19}$ : l'exposant fait plus que doubler à chaque étape. Une calculatrice affiche $u_3$ et $\sqrt{720}$ avec exactement les mêmes chiffres.

Si $u_n$ est exact à $10^{-p}$ près, alors $u_{n+1}$ est exact à $10^{-2p}$ près (pour $a \geqslant 1$)

Étape 1. On note $e_n = u_n - \sqrt{a}$ l'erreur. Pour $n \geqslant 1$, elle est positive, et l'égalité clé s'écrit $e_{n+1} = \dfrac{e_n^2}{2u_n}$.

Étape 2. Comme $u_n \geqslant \sqrt{a}$, on obtient

$$0 \leqslant e_{n+1} \leqslant \frac{e_n^2}{2\sqrt{a}}.$$

Étape 3. Si $a \geqslant 1$, alors $2\sqrt{a} \geqslant 2$, et si $e_n \leqslant 10^{-p}$, alors $e_{n+1} \leqslant \dfrac{10^{-2p}}{2} < 10^{-2p}$.

Conclusion. Chaque étape au moins double le nombre de décimales exactes (à un chiffre près, selon les arrondis). Pour $\sqrt{720}$, c'est encore mieux, car on divise par $2\sqrt{720} \approx 53{,}7$.

On dit que la convergence est quadratique. C'est très différent d'une suite géométrique de raison $\frac{1}{2}$, qui gagne un chiffre exact toutes les trois ou quatre étapes environ. Avec la méthode de Héron, $5$ étapes à partir d'un chiffre exact en donnent plus de $30$ ; c'est ce que fait le programme suivant. Il calcule avec des entiers géants (on multiplie tout par une grande puissance de $10$), ce qui permet de dépasser les $16$ chiffres d'une calculatrice.

a = 2 N = 10 ** 60 # on calcule avec 60 décimales u = 1 * N # u0 = 1, écrit avec 60 décimales ref = u for k in range(12): # beaucoup d'étapes pour avoir une référence très précise ref = (ref + a * N * N // ref) // 2 def decimales_exactes(x, y): s, t = str(x), str(y) i = 0 while i < len(s) and s[i] == t[i]: i = i + 1 return max(i - 1, 0) # le premier chiffre est la partie entière for n in range(1, 7): u = (u + a * N * N // u) // 2 texte = str(u) print("u" + str(n), "=", texte[0] + "," + texte[1:41], "... décimales exactes :", decimales_exactes(u, ref))

On obtient successivement $0$, $2$, $5$, $11$, $23$ puis $47$ décimales exactes de $\sqrt{2}$ : le nombre de décimales double bien, à une unité près.

Babylone : la tablette YBC 7289 Petite tablette d'argile ronde et beige, sur fond noir, sur laquelle sont gravés un carré, ses deux diagonales, et des signes cunéiformes le long d'un côté et d'une diagonale. La tablette YBC 7289 (Yale Babylonian Collection), environ $8$ cm de diamètre, vers 1800-1600 av. J.-C. Le long de la diagonale du carré est écrit, en base $60$, une valeur de $\sqrt{2}$ juste à environ $6 \times 10^{-7}$ près. Photographie A. Urcia, Yale Peabody Museum of Natural History, CC0, Wikimedia Commons (recadrée).

Cette petite tablette d'écolier, de l'époque paléo-babylonienne (vers 1800-1600 av. J.-C.), montre un carré et ses diagonales. Le côté porte le nombre $30$, et le long de la diagonale on lit, en numération sexagésimale (base $60$), les nombres $1\,;24,51,10$ et $42\,;25,35$.

Convertissons à la main, comme on le fait pour les heures, minutes et secondes, qui en sont les héritières :

$$1\,;24,51,10 = 1 + \frac{24}{60} + \frac{51}{60^2} + \frac{10}{60^3},$$

c'est-à-dire

$$1\,;24,51,10 \approx 1{,}414\,212\,96,$$

alors que $\sqrt{2} \approx 1{,}414\,213\,56$. L'écart est d'environ $6 \times 10^{-7}$ : six décimales exactes, plus de mille ans avant Héron. Le second nombre, $42\,;25,35 \approx 42{,}426\,4$, est la diagonale du carré de côté $30$, soit $30\sqrt{2}$ : le scribe applique le coefficient au cas particulier.

Comment l'a-t-on obtenu ? La tablette ne le dit pas, et les historiens en discutent encore. La méthode de Héron, partie de $\frac{3}{2}$, donne $\frac{17}{12}$ puis $\frac{577}{408} \approx 1{,}414\,215\,7$, qui, écrit en base $60$ et tronqué à trois chiffres après le point-virgule, donne exactement $1\,;24,51,10$. C'est compatible avec une méthode de type Héron, mais $\sqrt{2}$ lui-même, tronqué de la même façon, donne aussi $1\,;24,51,10$ : on ne peut pas conclure. D'autres textes babyloniens utilisent des approximations qui ressemblent à la première étape de Héron, d'où l'hypothèse souvent avancée d'une méthode transmise, mais elle reste une hypothèse.

On retrouve la même famille de fractions chez Archimède, qui encadre $\sqrt{3}$ par $\frac{265}{153}$ et $\frac{1351}{780}$ sans dire comment il les a trouvées. Or une étape de Héron à partir de $\frac{26}{15}$ donne

$$\begin{aligned} \frac{1}{2}\left(\frac{26}{15} + \frac{3 \times 15}{26}\right) &= \frac{676 + 675}{780} \\ &= \frac{1351}{780}. \end{aligned}$$
La méthode de Héron est une méthode de Newton

Chercher $\sqrt{a}$, c'est chercher la solution positive de l'équation $g(x) = 0$, avec $g(x) = x^2 - a$. La méthode de Newton remplace la courbe par sa tangente : à partir d'une valeur $u_n$, on trace la tangente à la courbe au point d'abscisse $u_n$, et l'on prend pour $u_{n+1}$ l'abscisse du point où elle coupe l'axe des abscisses.

La méthode de Newton appliquée à $x^2 - a$ redonne la formule de Héron

Étape 1. La tangente au point d'abscisse $u_n$ a pour équation $y = g'(u_n)(x - u_n) + g(u_n)$, avec $g'(u_n) = 2u_n$.

Étape 2. Elle coupe l'axe des abscisses quand $y = 0$, c'est-à-dire pour $x = u_n - \dfrac{g(u_n)}{g'(u_n)}$.

Étape 3. On calcule :

$$\begin{aligned} u_n - \frac{u_n^2 - a}{2u_n} &= \frac{2u_n^2 - u_n^2 + a}{2u_n} \\ &= \frac{1}{2}\left(u_n + \frac{a}{u_n}\right). \end{aligned}$$

C'est exactement la formule de Héron.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var petit = {fontSize: 11, useKatex: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false}; board.create('segment', [[0, 0], [4.45, 0]], ax); board.create('segment', [[0, -2.3], [0, 15]], ax); for (var t = 1; t <= 4; t++) { board.create('segment', [[t, 0], [t, -0.25]], ax); board.create('text', [t - 0.05, -1.8, String(t)], petit); } for (var v = 5; v <= 15; v += 5) { board.create('segment', [[0, v], [-0.06, v]], ax); board.create('text', [-0.45, v, String(v)], petit); } var a = 2; board.create('functiongraph', [function (x) { return x * x - a; }, 0, 4.15], {strokeColor: '#c62828', strokeWidth: 2, highlight: false}); var s0 = board.create('slider', [[0.3, -3.7], [2.6, -3.7], [0.6, 4, 4.1]], {withLabel: false}); function suite() { var u = [s0.Value()], k; for (k = 0; k < 3; k++) { u.push((u[k] + a / u[k]) / 2); } return u; } var c = board.create('curve', [[0], [0]], {strokeColor: '#1565c0', strokeWidth: 1.5, highlight: false}); c.updateDataArray = function () { var u = suite(), X = [], Y = [], k; for (k = 0; k < 3; k++) { X.push(u[k], u[k], u[k + 1], NaN); Y.push(0, u[k] * u[k] - a, 0, NaN); } this.dataX = X; this.dataY = Y; }; function nb(x) { return x.toFixed(6).replace('.', ','); } board.create('text', [2.75, -3.7, function () { return 'u0 = ' + s0.Value().toFixed(2).replace('.', ','); }], opt); board.create('text', [0.15, 14.3, function () { return 'u1 = ' + nb(suite()[1]); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('text', [0.15, 12.9, function () { return 'u2 = ' + nb(suite()[2]); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('text', [0.15, 11.5, function () { return 'u3 = ' + nb(suite()[3]); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('text', [0.15, 10.1, '√2 ≈ 1,414214'], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#c62828'}); En rouge, la courbe de $g(x) = x^2 - 2$. En bleu, les trois premières étapes : on monte jusqu'à la courbe, on suit la tangente jusqu'à l'axe, et l'on recommence. Le curseur règle la valeur de départ $u_0$ ; même en partant de $0{,}6$, trop bas, la première tangente renvoie à droite de $\sqrt{2}$, puis la suite descend vers $\sqrt{2}$.

La méthode de Newton (Newton vers 1670, Raphson en 1690, sous sa forme moderne avec Thomas Simpson en 1740) résout ainsi bien d'autres équations, et elle a en général la même convergence quadratique près de la solution. Elle est présentée en détail dans le texte Approximation des solutions d'une équation, avec la dichotomie et la méthode du point fixe, beaucoup plus lentes.

Les racines carrées dans les machines Calculatrices et processeurs

Une calculatrice ne connaît que des opérations élémentaires sur des chiffres. Pour une racine carrée, elle utilise soit une méthode « chiffre par chiffre », proche de la méthode de la potence apprise autrefois à l'école, soit une méthode de type Newton, selon les modèles. Dans les processeurs d'ordinateur, la norme IEEE 754, qui fixe depuis 1985 la façon de représenter et de calculer les nombres à virgule, impose que la racine carrée soit correctement arrondie : le résultat doit être le nombre représentable le plus proche de la vraie valeur. Les circuits y parviennent avec des algorithmes chiffre par chiffre ou avec des itérations de type Newton suivies d'une correction finale, selon les fabricants.

Un détail rend Newton particulièrement intéressant pour un circuit : la formule de Héron demande une division $\frac{a}{u_n}$, opération lente. On préfère souvent calculer d'abord $\frac{1}{\sqrt{a}}$, dont la méthode de Newton n'utilise que des multiplications, puis multiplier par $a$ (car $a \times \frac{1}{\sqrt{a}} = \sqrt{a}$).

La racine carrée inverse rapide de Quake III

Dans un jeu vidéo en trois dimensions, il faut sans cesse normaliser des vecteurs (les ramener à une longueur $1$, par exemple pour calculer l'éclairage d'une surface), donc diviser leurs coordonnées par $\sqrt{x^2 + y^2 + z^2}$. À la fin des années 1990, ces calculs coûtaient cher. Le code source du jeu Quake III Arena (1999), rendu public en 2005, contient une fonction devenue célèbre :

float Q_rsqrt(float number) {
    long i; float x2, y;
    x2 = number * 0.5F;
    y  = number;
    i  = * (long *) &y;             // lire les bits du nombre comme un entier
    i  = 0x5f3759df - (i >> 1);     // la constante « magique »
    y  = * (float *) &i;
    y  = y * (1.5F - (x2 * y * y)); // une étape de la méthode de Newton
    return y;
}

Elle calcule $\frac{1}{\sqrt{x}}$ en deux temps :

  • une première approximation, obtenue par une astuce sur l'écriture binaire des nombres à virgule : comme cette écriture contient l'exposant de $2$, décaler les bits d'un cran revient presque à diviser le logarithme de base $2$ par deux, donc à prendre une racine carrée ; la constante $\text{5f3759df}$ (en hexadécimal) corrige le résultat ;
  • une étape de Newton appliquée à l'équation $h(y) = \dfrac{1}{y^2} - x = 0$, qui donne la formule $y_{n+1} = y_n\left(\dfrac{3}{2} - \dfrac{x}{2}y_n^2\right)$, sans aucune division.
L'étape de Newton pour $\frac{1}{\sqrt{x}}$

Avec $h(y) = y^{-2} - x$, on a $h'(y) = -2y^{-3}$, donc

$$\begin{aligned} y - \frac{h(y)}{h'(y)} &= y + \frac{y^3}{2}\left(\frac{1}{y^2} - x\right) \\ &= y + \frac{y}{2} - \frac{x}{2}y^3, \end{aligned}$$

soit $y\left(\dfrac{3}{2} - \dfrac{x}{2}y^2\right)$.

Après cette unique étape, l'erreur relative ne dépasse pas environ $0{,}2\,\%$, largement assez pour l'œil d'un joueur. L'origine de la constante est restée longtemps mystérieuse ; des enquêtes publiées au milieu des années 2000 font remonter l'astuce à des travaux antérieurs, chez Silicon Graphics et ailleurs, sans qu'un auteur unique soit établi avec certitude. Les processeurs actuels ont des instructions dédiées, et l'astuce n'est plus utile, mais elle reste un bel exemple d'algorithme qui mêle représentation des nombres, logarithme et méthode de Newton.

Le programme ci-dessous ne reproduit pas l'astuce binaire, impossible à écrire simplement en Python, mais il montre l'effet de l'étape de Newton sans division à partir d'une première approximation grossière.

from math import sqrt def etape(x, y): return y * (1.5 - 0.5 * x * y * y) # aucune division for x in [2.0, 10.0, 720.0]: exacte = 1 / sqrt(x) y = exacte * 1.03 # une première approximation fausse de 3 % for k in range(1, 4): y = etape(x, y) print("x =", x, " étape", k, " erreur relative :", abs(y - exacte) / exacte) print(" donc racine de", x, "≈", x * y)

L'erreur relative passe d'environ $3\,\%$ à environ $0{,}14\,\%$, puis à environ $3 \times 10^{-6}$, puis à environ $1{,}2 \times 10^{-11}$ : la convergence est encore quadratique.

Des directions pour construire sa question

Ce texte n'est pas un Grand Oral. Il rassemble des connaissances dans lesquelles chacun peut choisir une direction, la creuser et formuler sa propre question. Quelques directions possibles :

Pour l'échange avec le jury : les notions du cours à maîtriser

Le jury peut interroger sur les chapitres de spécialité mobilisés. Avec ce thème, il est utile de connaître parfaitement : les suites définies par récurrence et le raisonnement par récurrence ; les suites monotones, majorées ou minorées, et le théorème de convergence monotone ; la limite d'une suite $u_{n+1} = f(u_n)$ avec $f$ continue ; la dérivation, les variations d'une fonction et l'équation d'une tangente ; le produit scalaire ; les boucles en Python.

Pour réviser ces chapitres, l'application Maths FlashBac reprend tout le cours de spécialité en cartes.

Pour aller plus loin