Comment est calculé un sinus ? Grand Oral · mathématiques, NSI, HGGSP Un support de connaissances pour construire sa propre question

← Tous les textes du Grand Oral

MathsNSIHGGSP

On tape « sin(1) » sur une calculatrice et la réponse $0{,}841\,470\,984\ldots$ s'affiche aussitôt. Pourtant, le sinus n'est pas une opération simple comme l'addition : aucune formule avec un nombre fini d'additions, de multiplications et de divisions ne donne exactement $\sin x$. Comment l'obtient-on alors ?

Pendant près de deux mille ans, on a recopié des tables calculées à la main par des astronomes. Aujourd'hui, une machine calcule le sinus à chaque appui sur une touche, avec des polynômes ou avec un algorithme de rotations. Ce texte suit cette histoire avec des outils de terminale : formules de trigonométrie, études de fonctions par la dérivée, suites récurrentes, algorithmes. Il rassemble des connaissances ; à chacun d'y choisir une direction et d'y construire sa question.

Sommaire
  1. Les cordes d'Hipparque et de Ptolémée
  2. Construire une table à la main
  3. Le problème du sinus de 1°
  4. Encadrer le sinus par des polynômes
  5. Dans la calculatrice : réduire, puis calculer
  6. L'algorithme CORDIC
  7. Calculateurs humains et erreurs célèbres
  8. Des directions pour construire sa question
Les cordes d'Hipparque et de Ptolémée

Les astronomes grecs avaient besoin de calculer des positions d'astres, donc des longueurs dans des triangles. Ils n'utilisaient pas le sinus mais la corde : dans un cercle de centre $O$, la corde associée à l'angle $\alpha = \widehat{AOB}$ est la longueur du segment $[AB]$.

Corde et sinus

Prenons un cercle de rayon $1$ et notons $I$ le milieu de $[AB]$. Le triangle $OAB$ est isocèle en $O$ ; la médiane $(OI)$ est donc aussi hauteur et bissectrice. Le triangle $OIA$ est rectangle en $I$, avec un angle $\widehat{AOI} = \dfrac{\alpha}{2}$. Alors

$$\sin\left(\frac{\alpha}{2}\right) = \frac{AI}{OA} = \frac{AI}{1} = \frac{AB}{2},$$

c'est-à-dire $\text{crd}(\alpha) = 2\sin\left(\dfrac{\alpha}{2}\right)$. Une table de cordes est donc une table de sinus déguisée : il suffit de diviser par deux et de prendre la moitié de l'angle.

var opt = {fontSize: 13, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var sa = board.create('slider', [[-1.05, -1.3], [0.35, -1.3], [30, 100, 180]], {withLabel: false, snapWidth: 1}); function nombre(x, d) { return x.toFixed(d).replace('.', ','); } function demi() { return Math.round(sa.Value()) * Math.PI / 360; } board.create('circle', [[0, 0], 1], {strokeColor: '#455a64', strokeWidth: 1.5, fixed: true, highlight: false}); var O = board.create('point', [0, 0], {name: 'O', size: 2, color: '#455a64', fixed: true, label: {offset: [-16, 2]}}); var A = board.create('point', [function () { return Math.cos(demi()); }, function () { return Math.sin(demi()); }], {name: 'A', size: 3, color: '#1565c0', fixed: true, label: {offset: [6, 8]}}); var B = board.create('point', [function () { return Math.cos(demi()); }, function () { return -Math.sin(demi()); }], {name: 'B', size: 3, color: '#1565c0', fixed: true, label: {offset: [6, -10]}}); var I = board.create('point', [function () { return Math.cos(demi()); }, 0], {name: 'I', size: 2, color: '#2e7d32', fixed: true, label: {offset: [-16, -10]}}); board.create('segment', [O, A], {strokeColor: '#9e9e9e', strokeWidth: 1, fixed: true, highlight: false}); board.create('segment', [O, B], {strokeColor: '#9e9e9e', strokeWidth: 1, fixed: true, highlight: false}); board.create('segment', [O, I], {strokeColor: '#9e9e9e', strokeWidth: 1, dash: 2, fixed: true, highlight: false}); board.create('segment', [A, B], {strokeColor: '#c62828', strokeWidth: 2, fixed: true, highlight: false}); board.create('segment', [A, I], {strokeColor: '#2e7d32', strokeWidth: 4, fixed: true, highlight: false}); board.create('text', [0.5, -1.3, function () { return 'α = ' + Math.round(sa.Value()) + '°'; }], opt); board.create('text', [-1.05, -1.52, function () { return 'corde AB = ' + nombre(2 * Math.sin(demi()), 4); }], opt); board.create('text', [-1.05, -1.74, function () { return 'AI = sin(α/2) = ' + nombre(Math.sin(demi()), 4); }], opt);

Déplacer le curseur pour changer l'angle α. La corde (en rouge) est le double du segment vert, qui mesure sin(α/2).

Les premières tables

La plus ancienne table connue est attribuée à Hipparque (IIe siècle avant notre ère) ; elle est perdue, et on la connaît par des reconstructions. Hipparque aurait pris un cercle de rayon $3\,438$ : ce nombre n'est pas choisi au hasard. Le tour complet mesure $360 \times 60 = 21\,600$ minutes d'angle, et un cercle de périmètre $21\,600$ a pour rayon $\dfrac{21\,600}{2\pi} \approx 3\,437{,}7$. Avec ce rayon, un petit arc et sa corde ont presque la même mesure.

Au IIe siècle de notre ère, Ptolémée publie dans l'Almageste une table des cordes de demi-degré en demi-degré, de $0{,}5°$ à $180°$, pour un cercle de rayon $60$. Les valeurs sont écrites en base soixante, avec trois « chiffres » après la virgule, ce qui correspond à environ cinq chiffres significatifs.

Le sinus lui-même apparaît en Inde, avec Aryabhata, au Ve siècle : on y tabule directement la demi-corde. Le mot voyage ensuite par l'arabe (jayb) puis le latin (sinus, « le pli »), à la suite d'une erreur de traduction souvent racontée. Les astronomes du monde arabe et persan (Abu al-Wafa, al-Biruni, al-Tusi…) améliorent ces tables, que l'Europe reprend à partir du XIIe siècle.

Construire une table à la main

Sans calculatrice, comment remplir une table ? On part de quelques valeurs exactes et on les combine avec des formules.

Les valeurs de départ

Le demi-carré et le demi-triangle équilatéral donnent, par le théorème de Pythagore, $\sin 30° = \dfrac{1}{2}$, $\sin 45° = \dfrac{\sqrt{2}}{2}$ et $\sin 60° = \dfrac{\sqrt{3}}{2}$. Les racines carrées s'extraient à la main, par exemple par la méthode de Héron.

Les formules qui font avancer

On utilise les formules d'addition (vues en première, démontrées par exemple avec le produit scalaire) :

$$\sin(a + b) = \sin a \cos b + \cos a \sin b,$$ $$\cos(a + b) = \cos a \cos b - \sin a \sin b.$$

Avec $b = -b$, on obtient de même $\sin(a - b) = \sin a \cos b - \cos a \sin b$. Avec $a = b$, on obtient $\cos 2a = 1 - 2\sin^2 a$, d'où la formule de l'angle moitié :

$$\sin^2\left(\frac{a}{2}\right) = \frac{1 - \cos a}{2}.$$

De $30°$ on passe à $15°$, $7{,}5°$… ; de $45°$ à $22{,}5°$, $11{,}25°$… Mais ces angles ne tombent pas sur des degrés entiers. Il manque un ingrédient : le pentagone régulier.

Le cosinus de 36°, démontré

Ptolémée utilise le pentagone régulier, dont l'angle au centre vaut $72°$. Voici une démonstration moderne de la valeur de $\cos 36°$.

Étape 1 : une formule pour $\sin 3a$. On écrit $3a = 2a + a$ :

$$\sin 3a = \sin 2a \cos a + \cos 2a \sin a.$$

Or $\sin 2a = 2\sin a \cos a$ et $\cos 2a = 1 - 2\sin^2 a$, donc, en mettant $\sin a$ en facteur,

$$\sin 3a = \sin a\,(2\cos^2 a + 1 - 2\sin^2 a).$$

En remplaçant $\cos^2 a$ par $1 - \sin^2 a$, la parenthèse devient $3 - 4\sin^2 a$, d'où

$$\sin 3a = 3\sin a - 4\sin^3 a.$$

Étape 2 : l'équation. Posons $x = 36°$. Alors $5x = 180°$, donc $3x = 180° - 2x$ et $\sin 3x = \sin(180° - 2x) = \sin 2x$. Ainsi

$$3\sin x - 4\sin^3 x = 2\sin x\cos x.$$

Étape 3 : simplifier. Comme $\sin x \neq 0$, on divise par $\sin x$ : $3 - 4\sin^2 x = 2\cos x$, puis, avec $\sin^2 x = 1 - \cos^2 x$ :

$$4\cos^2 x - 2\cos x - 1 = 0.$$

Étape 4 : résoudre. C'est une équation du second degré en $c = \cos x$, de discriminant $\Delta = 4 + 16 = 20$. Ses solutions sont $\dfrac{2 \pm \sqrt{20}}{8} = \dfrac{1 \pm \sqrt{5}}{4}$. Comme $\cos 36° > 0$, on garde la solution positive :

$$\cos 36° = \frac{1 + \sqrt{5}}{4} \approx 0{,}809\,017.$$

On reconnaît la moitié du nombre d'or $\varphi = \dfrac{1 + \sqrt{5}}{2}$.

À la main : de 36° à 3°
  • $\sin 36° = \sqrt{1 - \cos^2 36°}$, donc $\sin 36° \approx 0{,}587\,785$.
  • Formule de soustraction $\sin(a - b) = \sin a \cos b - \cos a \sin b$ avec $a = 36°$ et $b = 30°$ : on obtient environ $0{,}509\,037 - 0{,}404\,508$, donc $\sin 6° \approx 0{,}104\,528$.
  • Angle moitié : $\sin 3° = \sqrt{\dfrac{1 - \cos 6°}{2}} \approx 0{,}052\,336$, puis $1{,}5°$, $0{,}75°$…

En combinant ces angles par additions, on remplit une table de $3°$ en $3°$, puis plus finement. Mais un angle résiste : $1°$.

Un livre ancien ouvert dans une vitrine de musée : deux pages couvertes de colonnes de nombres serrés. Un cartel indique : Peurbach et Regiomontanus, Tractatus super propositiones Ptolemaei de sinubus et chordis, édition de 1541. Une table de sinus de Peurbach et Regiomontanus (édition imprimée de 1541), exposée au Computer History Museum : des colonnes de nombres calculés à la main. Photo : Arnold Reinhold, Wikimedia Commons, licence CC BY-SA 4.0.
Le problème du sinus de 1°

Partager un angle en trois avec la règle et le compas est impossible en général (on l'a démontré au XIXe siècle). Les formules précédentes ne donnent donc pas $\sin 1°$ à partir de $\sin 3°$. Deux solutions ont été trouvées.

Ptolémée : un encadrement

Ptolémée utilise une propriété géométrique que l'on peut écrire aujourd'hui ainsi : la fonction $f : x \mapsto \dfrac{\sin x}{x}$ est décroissante sur $\left]0\,;\dfrac{\pi}{2}\right]$.

Étape 1 : la dérivée. $f$ est un quotient de fonctions dérivables, et

$$f'(x) = \frac{x\cos x - \sin x}{x^2}.$$

Le signe de $f'(x)$ est celui du numérateur $g(x) = x\cos x - \sin x$.

Étape 2 : étudier $g$. $g'(x) = \cos x - x\sin x - \cos x$, soit $g'(x) = -x\sin x$. Sur $\left]0\,;\dfrac{\pi}{2}\right]$, $x > 0$ et $\sin x > 0$, donc $g'(x) < 0$ : $g$ est strictement décroissante sur $\left[0\,;\dfrac{\pi}{2}\right]$.

Étape 3 : conclure. Comme $g(0) = 0$, on a $g(x) < 0$ pour $x > 0$, donc $f'(x) < 0$ : $f$ est strictement décroissante.

À la main. Changer d'unité d'angle multiplie le quotient $\dfrac{\sin a}{a}$ par une constante positive, ce qui ne change pas son sens de variation : on peut donc raisonner en degrés. Comme $0{,}75 < 1 < 1{,}5$ :

  • $\dfrac{\sin 1°}{1} < \dfrac{\sin 0{,}75°}{0{,}75}$, donc $\sin 1° < \dfrac{4}{3}\sin 0{,}75° \approx 0{,}017\,452\,8$ ;
  • $\dfrac{\sin 1°}{1} > \dfrac{\sin 1{,}5°}{1{,}5}$, donc $\sin 1° > \dfrac{2}{3}\sin 1{,}5° \approx 0{,}017\,451\,3$.

L'encadrement donne $\sin 1° \approx 0{,}017\,45$, assez pour la table de Ptolémée.

Al-Kashi : une suite récurrente

Vers 1420, à Samarcande, à l'observatoire du prince Ulugh Beg, l'astronome persan Jamshid al-Kashi va beaucoup plus loin. Il part de la formule $\sin 3a = 3\sin a - 4\sin^3 a$ avec $a = 1°$ : le nombre $x = \sin 1°$ est solution de l'équation du troisième degré

$$3x - 4x^3 = \sin 3°,$$

soit

$$x = \frac{\sin 3° + 4x^3}{3}.$$

Il calcule alors les termes de la suite définie par $u_0 = \dfrac{\sin 3°}{3}$ et $u_{n+1} = \dfrac{\sin 3° + 4u_n^3}{3}$ : c'est la méthode du point fixe. Comme $x$ est très petit, le terme $4x^3$ ne change que des décimales lointaines, et chaque étape fixe environ cinq décimales de plus.

from math import sqrt # sin 3° obtenu sans la fonction sinus, comme dans une table faite à la main c36 = (1 + sqrt(5)) / 4 s36 = sqrt(1 - c36**2) s30, c30 = 1/2, sqrt(3)/2 s6 = s36*c30 - c36*s30 # sin(36° - 30°) c6 = sqrt(1 - s6**2) s3 = sqrt((1 - c6) / 2) # angle moitié print("sin 3° =", s3) u = s3 / 3 # u0 for n in range(1, 5): u = (s3 + 4*u**3) / 3 print("u" + str(n), "=", u)

Al-Kashi obtient une valeur de $\sin 1°$ équivalente à environ seize décimales exactes : $\sin 1° \approx 0{,}017\,452\,406\,437\,283\,5$. Le même savant avait calculé $\pi$ avec seize décimales en 1424. La convergence de cette méthode et le choix de la fonction sont étudiés dans le texte Approximation des solutions d'une équation.

Regiomontanus et le passage au décimal

Au XVe siècle, l'astronome allemand Johannes Müller, dit Regiomontanus (1436-1476), achève l'œuvre de son maître Peurbach et rédige le premier grand traité européen de trigonométrie, De triangulis omnimodis (1464, imprimé en 1533). Ses tables de sinus utilisent un rayon de $6\,000\,000$, puis de $10\,000\,000$ : avec un rayon égal à une puissance de dix, la table donne en fait les décimales de $\sin x$, sans le dire. C'est un pas vers l'écriture décimale, que Viète et Stevin généraliseront à la fin du XVIe siècle.

Encadrer le sinus par des polynômes

Un polynôme ne demande que des additions et des multiplications. L'idée est donc d'approcher $\sin x$ par des polynômes, en démontrant des inégalités par des études de fonctions successives. Dans toute cette partie, $x$ est en radians et $x \geqslant 0$.

Une cascade d'études de fonctions

Étape 1 : $\sin x \leqslant x$. Soit $h_1(x) = x - \sin x$. Alors $h_1'(x) = 1 - \cos x \geqslant 0$, donc $h_1$ est croissante sur $[0\,;+\infty[$. Comme $h_1(0) = 0$, on a $h_1(x) \geqslant 0$, c'est-à-dire $\sin x \leqslant x$.

Étape 2 : $\cos x \geqslant 1 - \dfrac{x^2}{2}$. Soit $h_2(x) = \cos x - 1 + \dfrac{x^2}{2}$. Alors $h_2'(x) = -\sin x + x = h_1(x) \geqslant 0$, et $h_2(0) = 0$, donc $h_2(x) \geqslant 0$.

Étape 3 : $\sin x \geqslant x - \dfrac{x^3}{6}$. Soit $h_3(x) = \sin x - x + \dfrac{x^3}{6}$. Alors $h_3'(x) = \cos x - 1 + \dfrac{x^2}{2} = h_2(x) \geqslant 0$, et $h_3(0) = 0$, donc $h_3(x) \geqslant 0$.

Conclusion. Pour tout réel $x \geqslant 0$ :

$$x - \frac{x^3}{6} \leqslant \sin x \leqslant x.$$

Chaque étape réutilise la précédente : la dérivée de la nouvelle fonction est l'ancienne. On peut continuer de la même façon : $h_4(x) = 1 - \dfrac{x^2}{2} + \dfrac{x^4}{24} - \cos x$ a pour dérivée $h_3(x)$, puis $h_5(x) = x - \dfrac{x^3}{6} + \dfrac{x^5}{120} - \sin x$ a pour dérivée $h_4(x)$. Toutes sont nulles en $0$ et positives, ce qui donne le nouvel encadrement

$$x - \frac{x^3}{6} \leqslant \sin x \leqslant x - \frac{x^3}{6} + \frac{x^5}{120}.$$

Les dénominateurs $6 = 3!$ et $120 = 5!$ sont des factorielles, et le motif continue avec $7! = 5\,040$, $9! = 362\,880$…

La précision obtenue

L'encadrement dit aussi que l'erreur commise en remplaçant $\sin x$ par $x - \dfrac{x^3}{6}$ est au plus $\dfrac{x^5}{120}$.

  • Pour $x = 0{,}1$ : $0{,}1 - \dfrac{0{,}001}{6} \approx 0{,}099\,833\,3$, avec une erreur au plus $\dfrac{0{,}1^5}{120} \approx 8{,}3 \times 10^{-8}$.
  • Pour $1°$, soit $x = \dfrac{\pi}{180} \approx 0{,}017\,453\,3$ : l'erreur est au plus $1{,}4 \times 10^{-11}$. Deux termes suffisent pour retrouver dix décimales de la valeur d'al-Kashi.
  • Pour $x = \dfrac{\pi}{4}$ : l'erreur atteint environ $0{,}002\,5$, et tombe à $4 \times 10^{-5}$ en ajoutant le terme $\dfrac{x^5}{120}$.
  • Pour $x = 3$ : $3 - 4{,}5 + 2{,}025 = 0{,}525$, alors que $\sin 3 \approx 0{,}141$. Loin de $0$, ces polynômes ne valent plus rien.
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false}; board.create('segment', [[0, 0], [6.8, 0]], ax); board.create('segment', [[0, -1.6], [0, 1.6]], ax); board.create('segment', [[0, 1], [-0.1, 1]], ax); board.create('segment', [[0, -1], [-0.1, -1]], ax); board.create('text', [-0.45, 1, '1'], opt); board.create('text', [-0.5, -1, '−1'], opt); var noms = ['π/2', 'π', '3π/2', '2π']; for (var i = 1; i <= 4; i++) { board.create('segment', [[i * Math.PI / 2, -1.6], [i * Math.PI / 2, 1.6]], {strokeColor: '#cfd8dc', strokeWidth: 1, dash: 2, fixed: true, highlight: false}); board.create('text', [i * Math.PI / 2 - 0.2, -1.78, noms[i - 1]], opt); } board.create('functiongraph', [function (x) { return Math.sin(x); }, 0, 6.8], {strokeColor: '#1565c0', strokeWidth: 3, highlight: false}); var sd = board.create('slider', [[0.1, -2.25], [3.2, -2.25], [0, 2, 6]], {withLabel: false, snapWidth: 1}); function degre() { return 2 * Math.round(sd.Value()) + 1; } function P(x) { var n = degre(), s = 0, t = x, k = 1; while (k <= n) { s += t; t = -t * x * x / ((k + 1) * (k + 2)); k += 2; } return s; } board.create('functiongraph', [function (x) { var y = P(x); return Math.abs(y) > 1.6 ? NaN : y; }, 0, 6.8], {strokeColor: '#c62828', strokeWidth: 2, highlight: false}); function limite() { var x = 0; while (x < 6.8 && Math.abs(P(x) - Math.sin(x)) < 0.001) { x += 0.005; } return x; } board.create('text', [3.45, -2.25, function () { return 'polynôme de degré ' + degre(); }], opt); board.create('text', [0.1, -2.62, function () { var x = limite(); return 'écart inférieur à 0,001 pour x < ' + x.toFixed(2).replace('.', ','); }], opt);

En bleu, la courbe du sinus ; en rouge, le polynôme x − x³/6 + x⁵/120 − … du degré choisi. Plus le degré augmente, plus l'approximation reste bonne loin de 0.

Ces polynômes sont les débuts d'une somme infinie, la série du sinus, trouvée en Inde par l'école du Kerala (Madhava, vers 1400, d'après des textes plus tardifs) puis en Europe par Newton (1669). L'animation sur la série du sinus montre les polynômes successifs.

Dans la calculatrice : réduire, puis calculer Ramener l'angle près de 0

Puisque les polynômes ne sont bons que près de $0$, une machine commence toujours par réduire l'angle, grâce aux propriétés du cercle trigonométrique :

  • périodicité : $\sin(x + 2k\pi) = \sin x$ pour tout entier $k$ ;
  • quarts de tour : $\sin\left(r + \dfrac{\pi}{2}\right) = \cos r$, $\sin(r + \pi) = -\sin r$, $\sin\left(r + \dfrac{3\pi}{2}\right) = -\cos r$.

On écrit $x = k\dfrac{\pi}{2} + r$, où $k$ est l'entier le plus proche de $\dfrac{x}{\pi/2}$ ; alors $r$ est compris entre $-\dfrac{\pi}{4}$ et $\dfrac{\pi}{4}$, et il ne reste qu'à calculer $\sin r$ ou $\cos r$.

À la main, $\sin 100$. On trouve $\dfrac{100}{\pi/2} \approx 63{,}66$, donc $k = 64$ et $r = 100 - 32\pi \approx -0{,}531\,0$. Comme $64$ est un multiple de $4$ (un nombre entier de tours), $\sin 100 = \sin r$. Avec trois termes, $r - \dfrac{r^3}{6} + \dfrac{r^5}{120} \approx -0{,}506\,4$, ce que confirme la calculatrice : $\sin 100 \approx -0{,}506\,37$.

Un piège. Pour réduire, il faut connaître $\pi$ avec beaucoup de chiffres : pour $x = 10^{20}$, une erreur minuscule sur $\pi$, multipliée par un $k$ gigantesque, fausse tout. Les bibliothèques de calcul modernes gardent pour cela des centaines de chiffres de $\dfrac{2}{\pi}$. L'instruction « fsin » des processeurs Intel, qui réduisait avec une valeur de $\pi$ sur $66$ bits, donnait des résultats faux près des multiples de $\pi$ ; la documentation d'Intel a été corrigée en 2014, après la publication de ce défaut.

from math import pi, sin def poly_sin(r): return r - r**3/6 + r**5/120 - r**7/5040 + r**9/362880 def poly_cos(r): return 1 - r**2/2 + r**4/24 - r**6/720 + r**8/40320 def mon_sinus(x): k = int(round(x / (pi/2))) # nombre de quarts de tour r = x - k * pi/2 # r entre -pi/4 et pi/4 q = k % 4 if q == 0: return poly_sin(r) if q == 1: return poly_cos(r) if q == 2: return -poly_sin(r) return -poly_cos(r) for x in [0.5, 2, 100, 1000]: print(x, mon_sinus(x), sin(x))

Sur $\left[-\dfrac{\pi}{4}\,;\dfrac{\pi}{4}\right]$, ces polynômes de degré $9$ et $8$ font une erreur inférieure à $10^{-7}$. Les vraies bibliothèques utilisent des polynômes un peu différents, aux coefficients ajustés par ordinateur pour répartir l'erreur sur tout l'intervalle.

L'algorithme CORDIC

Les premières calculatrices ne savaient pas multiplier vite. En 1959, l'ingénieur américain Jack Volder, qui travaille sur l'ordinateur de navigation d'un bombardier, publie une méthode qui calcule sinus et cosinus avec seulement des additions et des décalages : CORDIC (COordinate Rotation DIgital Computer).

Tourner un point

Le point $M(x\,;y)$ du cercle de rayon $\rho$ s'écrit $x = \rho\cos a$, $y = \rho\sin a$. Tournons-le d'un angle $t$ : le nouveau point a pour coordonnées $\rho\cos(a + t)$ et $\rho\sin(a + t)$. Les formules d'addition donnent

$$x' = x\cos t - y\sin t,$$ $$y' = x\sin t + y\cos t.$$

En mettant $\cos t$ en facteur :

$$x' = \cos t\,(x - y\tan t),$$ $$y' = \cos t\,(y + x\tan t).$$

L'astuce de Volder. On ne tourne que d'angles $t_k$ tels que $\tan t_k = 2^{-k}$ : $45°$, $26{,}565°$, $14{,}036°$… Multiplier par $2^{-k}$ en binaire, c'est décaler la virgule de $k$ rangs, comme diviser par $10$ en décimal : aucune vraie multiplication. Le facteur $\cos t_k$ est mis de côté : comme $\cos t = \dfrac{1}{\sqrt{1 + \tan^2 t}}$, le produit de tous ces facteurs est un nombre fixe, $K \approx 0{,}607\,253$, calculé une fois pour toutes. On part donc du point $(K\,;0)$.

À la main : viser 30°

À chaque étape, on tourne dans le sens qui rapproche de l'angle visé. Le tableau suit l'angle qu'il reste à parcourir.

Étape $k$Angle $t_k$SensReste
$0$$45°$$+$$-15°$
$1$$26{,}565°$$-$$11{,}565°$
$2$$14{,}036°$$+$$-2{,}471°$
$3$$7{,}125°$$-$$4{,}654°$
$4$$3{,}576°$$+$$1{,}077°$
$5$$1{,}790°$$+$$-0{,}712°$
$6$$0{,}895°$$-$$0{,}183°$

Le reste diminue par à-coups, et les angles $t_k$ sont à peu près divisés par deux à chaque étape : on gagne environ un chiffre binaire par étape. On admet que cette suite d'angles permet d'atteindre tout angle entre $-99°$ et $99°$ environ.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false}; board.create('segment', [[0, 0], [1.15, 0]], ax); board.create('segment', [[0, 0], [0, 1.1]], ax); board.create('arc', [[0, 0], [1, 0], [0, 1]], {strokeColor: '#9e9e9e', strokeWidth: 1, fixed: true, highlight: false}); var sv = board.create('slider', [[-0.2, -0.3], [0.55, -0.3], [0, 30, 90]], {withLabel: false, snapWidth: 1}); var sn = board.create('slider', [[-0.2, -0.5], [0.55, -0.5], [0, 3, 12]], {withLabel: false, snapWidth: 1}); var N = 30, K = 1, k; for (k = 0; k < N; k++) { K = K / Math.sqrt(1 + Math.pow(4, -k)); } function etapes(n) { var x = K, y = 0, z = Math.round(sv.Value()) * Math.PI / 180, P = [[x, y]], d, xn; for (var j = 0; j < n; j++) { d = z >= 0 ? 1 : -1; xn = x - d * y * Math.pow(2, -j); y = y + d * x * Math.pow(2, -j); x = xn; z -= d * Math.atan(Math.pow(2, -j)); P.push([x, y]); } return P; } board.create('segment', [[0, 0], [function () { var a = Math.round(sv.Value()) * Math.PI / 180; return 1.1 * Math.cos(a); }, function () { var a = Math.round(sv.Value()) * Math.PI / 180; return 1.1 * Math.sin(a); }]], {strokeColor: '#2e7d32', strokeWidth: 1.5, dash: 2, fixed: true, highlight: false}); var c = board.create('curve', [[0], [0]], {strokeColor: '#9e9e9e', strokeWidth: 1, highlight: false}); c.updateDataArray = function () { var P = etapes(Math.round(sn.Value())), X = [], Y = []; for (var j = 0; j < P.length; j++) { X.push(0, P[j][0], NaN); Y.push(0, P[j][1], NaN); } this.dataX = X; this.dataY = Y; }; var M = board.create('point', [function () { var P = etapes(Math.round(sn.Value())); return P[P.length - 1][0]; }, function () { var P = etapes(Math.round(sn.Value())); return P[P.length - 1][1]; }], {name: '', size: 3, color: '#c62828', fixed: true}); board.create('segment', [[0, 0], M], {strokeColor: '#c62828', strokeWidth: 2.5, fixed: true, highlight: false}); board.create('text', [0.62, -0.3, function () { return 'angle visé : ' + Math.round(sv.Value()) + '°'; }], opt); board.create('text', [0.62, -0.5, function () { return Math.round(sn.Value()) + ' étape(s)'; }], opt); board.create('text', [-0.2, -0.68, function () { var P = etapes(Math.round(sn.Value())); return 'y = ' + P[P.length - 1][1].toFixed(5).replace('.', ','); }], opt); board.create('text', [0.5, -0.68, function () { return 'sinus visé = ' + Math.sin(Math.round(sv.Value()) * Math.PI / 180).toFixed(5).replace('.', ','); }], opt);

En vert pointillé, la direction visée ; en gris, les positions successives ; en rouge, la position après le nombre d'étapes choisi. Son ordonnée $y$ se rapproche du sinus, et le point finit sur le cercle de rayon 1.

from math import atan, sqrt, sin, radians N = 30 angles = [atan(2**-k) for k in range(N)] # t_k, en radians K = 1 for k in range(N): K = K / sqrt(1 + 4**-k) def cordic(theta): # theta en radians, entre -pi/2 et pi/2 x, y, z = K, 0, theta for k in range(N): d = 1 if z >= 0 else -1 x, y = x - d*y*2**-k, y + d*x*2**-k z = z - d*angles[k] return x, y # (cos theta, sin theta) print("K =", K) c, s = cordic(radians(30)) print("sin 30° :", s, " cos 30° :", c) print("sin 1 :", cordic(1)[1], " bibliothèque :", sin(1))

Dans une puce, la boucle ne fait que des additions, des décalages et des lectures dans une petite table d'angles. Une variante de ces idées équipait la HP-35 de 1972, première calculatrice scientifique de poche, et de nombreuses calculatrices ensuite ; on trouve encore CORDIC dans des circuits simples où la multiplication coûte cher.

Une calculatrice de poche HP-35, noire, à touches grises et bleues, avec un affichage rouge à diodes indiquant un nombre. La HP-35 (1972), première calculatrice scientifique de poche : une touche « sin » calculée en une fraction de seconde. Photo : Seth Morabito, Wikimedia Commons, licence CC BY 2.0.
Calculateurs humains et erreurs célèbres Les tables de Prony : une usine à calculer

Sous la Révolution, la France adopte le système métrique et veut aussi diviser l'angle droit en $100$ grades. Il faut de nouvelles tables de sinus et de logarithmes, plus précises que toutes les précédentes, pour le cadastre. L'ingénieur Gaspard de Prony dirige ce travail à partir de 1791. Inspiré, raconte-t-il, par la division du travail dans une manufacture d'épingles décrite par l'économiste Adam Smith, il organise trois niveaux :

  • quelques mathématiciens choisissent les formules ;
  • des calculateurs qualifiés préparent les valeurs de départ ;
  • plusieurs dizaines d'exécutants ne font que des additions et des soustractions. Selon un récit souvent repris, beaucoup étaient d'anciens coiffeurs, privés de travail quand les perruques de l'Ancien Régime sont passées de mode.

Pourquoi seulement des additions ? Grâce à la méthode des différences. Sur un petit intervalle, le sinus est très proche d'un polynôme, et pour un polynôme de degré $3$, les différences troisièmes sont constantes. Exemple avec $u_n = n^3$ :

$n$$0$$1$$2$$3$$4$$5$
$n^3$$0$$1$$8$$27$$64$$125$
différences$1$$7$$19$$37$$61$
différences secondes$6$$12$$18$$24$
différences troisièmes$6$$6$$6$

On le démontre : $(n+1)^3 - n^3 = 3n^2 + 3n + 1$, dont la différence vaut $6n + 6$, dont la différence vaut $6$. En remontant le tableau, chaque nouvelle ligne s'obtient par trois additions : $24 + 6 = 30$, $61 + 30 = 91$, $125 + 91 = 216 = 6^3$.

Les tables du cadastre, terminées vers 1801, remplissent de nombreux volumes manuscrits mais ne sont pas publiées en entier à l'époque, faute d'argent. Elles inspirent l'Anglais Charles Babbage, qui conçoit à partir de 1822 une « machine à différences » pour produire des tables sans erreur humaine, celles des tables de navigation étant alors redoutées des marins.

Un mécanisme en laiton dans une vitrine : des colonnes de roues dentées portant des chiffres, empilées entre deux plaques et actionnées par une manivelle. Une partie de la machine à différences numéro 1 de Babbage, au Science Museum de Londres : chaque colonne de roues garde un nombre, et la machine ne fait que des additions. Photo : Marcin Wichary, Wikimedia Commons, licence CC BY 2.0.

Jusqu'au milieu du XXe siècle, le mot computer désigne une personne qui calcule : souvent des femmes, à l'observatoire de Harvard comme à la NASA (voir le texte sur les missions Apollo et celui sur Nicole-Reine Lepaute).

Le bug du Pentium (1994)

En 1994, Thomas Nicely, professeur de mathématiques en Virginie, calcule des sommes d'inverses de nombres premiers jumeaux et obtient des résultats incohérents. Il remonte jusqu'au processeur : le Pentium d'Intel se trompe dans certaines divisions. Exemple devenu célèbre :

$$\frac{4\,195\,835}{3\,145\,727} = 1{,}333\,820\,449\ldots$$

alors que le processeur affichait $1{,}333\,739\,068\ldots$, faux dès la quatrième décimale. L'algorithme de division lisait ses chiffres dans une table interne de plus d'un millier de cases, dont cinq avaient été oubliées. Les cas faux étaient rares, mais la confiance était perdue : Intel a dû remplacer les processeurs et a annoncé une perte de $475$ millions de dollars en janvier 1995.

Un processeur Intel Pentium vu de dessus : une puce carrée gravée du logo Intel et du mot Pentium. Un processeur Intel Pentium de première génération. Photo : Konstantin Lanzet, Wikimedia Commons, licence GFDL.

Le bug concerne la division et non le sinus, mais la leçon est la même que pour l'instruction « fsin » : une machine ne « sait » pas calculer, elle exécute un algorithme et des tables écrits par des humains. D'autres erreurs de calcul en machine, comme celle du missile Patriot en 1991, sont racontées dans le texte Suites récurrentes et chaos.

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 : le cercle trigonométrique, le radian, les valeurs remarquables et les formules d'addition ; les fonctions sinus et cosinus, leurs dérivées et leur périodicité ; la dérivée d'un quotient et l'étude du sens de variation ; les suites définies par une relation de récurrence et leur limite ; les équations du second degré.

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

Pour aller plus loin