From a36e9b5dbac6247b9dcf49382be61eaa0cfe7ae9 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Tue, 19 Oct 2021 00:47:00 +0200
Subject: [PATCH] =?UTF-8?q?recursivit=C3=A9=20finie?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 slides/cours_5.md | 246 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 226 insertions(+), 20 deletions(-)

diff --git a/slides/cours_5.md b/slides/cours_5.md
index 8de07ce..5d8bb24 100644
--- a/slides/cours_5.md
+++ b/slides/cours_5.md
@@ -324,7 +324,7 @@ $$
 
 * Comportement indéfini!
 
-# Nombres à virgule (1/N)
+# Nombres à virgule (1/3)
 
 ## Comment manipuler des nombres à virgule?
 
@@ -352,7 +352,7 @@ int main(int argc, char *argv[]) {
 
 ## Que se passe-t-il donc?
 
-# Nombres à virgule (2/N)
+# Nombres à virgule (2/3)
 
 ## Nombres à virgule fixe
 
@@ -379,7 +379,7 @@ $$
 * Tous les nombres `< 0.0625`.
 * Tous les nombres dont la décimale est pas un multiple de `0.0625`.
 
-# Nombres à virgule (3/N)
+# Nombres à virgule (3/3)
 
 ## Nombres à virgule fixe
 
@@ -431,7 +431,7 @@ La précision des nombres est **variable**:
 
 * On a uniquement un nombre de chiffres **significatifs**.
 $$
-123456\cdot 10^23+ 123456\cdot 10^{-23}.
+123456\cdot 10^{23}+ 123456\cdot 10^{-23}.
 $$
 
 ## Quel inconvénient y a-t-il?
@@ -440,7 +440,7 @@ $$
 
 Ce mélange d'échelles entraîne un **perte de précision**.
 
-# Nombres à virgule flottante simple précision (1/N)
+# Nombres à virgule flottante simple précision (1/4)
 
 Aussi appelés *IEEE 754 single-precision binary floating point*.
 
@@ -458,7 +458,7 @@ $$
 $$
 ## Calculer la valeur décimale du nombre ci-dessus
 
-# Nombres à virgule flottante simple précision (2/N)
+# Nombres à virgule flottante simple précision (2/4)
 
 ![Un exercice de nombres à virgule flottante 32 bits. Source:
 [Wikipedia](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#/media/File:Float_example.svg)](figs/Float_example.svg)
@@ -471,7 +471,7 @@ $$
 &\Rightarrow (-1)^0\cdot 2^{-3}\cdot 1.25=0.15625
 \end{align}
 
-# Nombres à virgule flottante simple précision (3/N)
+# Nombres à virgule flottante simple précision (3/4)
 
 ## Quel nombre ne peux pas être vraiment représenté?
 
@@ -487,9 +487,9 @@ $$
 $$
 \mbox{valeur normale},
 $$
-* Sinon `1111111` donne `NaN`.
+* Sinon `11111111` donne `NaN`.
 
-# Nombres à virgule flottante simple précision (4/N)
+# Nombres à virgule flottante simple précision (4/4)
 
 ## Quels sont les plus petits/grands nombres positifs représentables?
 
@@ -587,7 +587,7 @@ $$
 
 . . .
 
-Ou en d'autres termes, pour quel $\varepsilon>0$ on a
+Ou en d'autres termes, pour quel $\varepsilon>0$ (appelé `epsilon-machine`) on a
 $$
 1+\varepsilon = 1,
 $$
@@ -613,7 +613,7 @@ while ((float)1.0 + (float)0.5 * eps != (float)1.0) {
 printf("eps = %g\n", eps);
 ```
 
-# Erreurs d'arrondi (1/N)
+# Erreurs d'arrondi
 
 Et jusqu'ici on a encore pas fait d'arithmétique!
 
@@ -634,20 +634,226 @@ Soit une erreur de près de 1/5e!
 
 . . .
 
-Le même phénomène se produit (à plus petite échelle) avec les `float` ou
+## Le même phénomène se produit (à plus petite échelle) avec les `float` ou
 `double`.
 
-<!-- # TODO --
+# Exemple de récursivité (1/2)
 
-<!-- ## Entiers, entiers non-signés -->
+## La factorielle
 
-<!-- ## Complément à 1, 2 -->
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
+    }
+}
+```
+
+. . .
+
+## Que se passe-t-il quand on fait `factorial(4)`?
+
+. . .
+
+## On empile les appels
+
++----------------+----------------+----------------+----------------+
+|                |                |                | `factorial(1)` |
++----------------+----------------+----------------+----------------+
+|                |                | `factorial(2)` | `factorial(2)` |
++----------------+----------------+----------------+----------------+
+|                | `factorial(3)` | `factorial(3)` | `factorial(3)` |
++----------------+----------------+----------------+----------------+
+| `factorial(4)` | `factorial(4)` | `factorial(4)` | `factorial(4)` |
++----------------+----------------+----------------+----------------+
+
+# Exemple de récursivité (2/2)
+
+## La factorielle
+
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
+    }
+}
+```
+
+. . .
+
+## Que se passe-t-il quand on fait `factorial(4)`?
+
+. . .
+
+## On dépile les calculs
+
++----------------+----------------+----------------+----------------+
+|  `1`           |                |                |                |
++----------------+----------------+----------------+----------------+
+| `factorial(2)` |  `2 * 1 = 2`   |                |                |
++----------------+----------------+----------------+----------------+
+| `factorial(3)` | `factorial(3)` |  `3 * 2 = 6`   |                |
++----------------+----------------+----------------+----------------+
+| `factorial(4)` | `factorial(4)` | `factorial(4)` |  `4 * 6 = 24`  |
++----------------+----------------+----------------+----------------+
+
+# La récursivité (1/4)
+
+## Formellement 
+
+* Une condition de récursivité - qui *réduit* les cas successifs vers...
+* Une condition d'arrêt - qui retourne un résultat
+
+## Pour la factorielle, qui est qui?
+
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
+    }
+}
+```
+
+# La récursivité (2/4)
+
+## Formellement 
+
+* Une condition de récursivité - qui *réduit* les cas successifs vers...
+* Une condition d'arrêt - qui retourne un résultat
+
+## Pour la factorielle, qui est qui?
+
+```C
+int factorial(int n) {
+    if (n > 1) { // Condition de récursivité
+        return n * factorial(n - 1);
+    } else {     // Condition d'arrêt
+        return 1;
+    }
+}
+```
+
+# La récursivité (3/4)
+
+## Exercice: trouver l'$\varepsilon$-machine pour un `double`
+
+. . .
+
+```C
+double epsilon_machine(double eps) {
+    if (1.0 + eps != 1.0) {
+        return epsilon_machine(eps / 2.0);
+    } else {
+        return eps;
+    }
+}
+```
+
+# La récursivité (4/4)
+
+## Exercice: que fait ce code récursif?
+
+```C
+void recurse(int n) {
+    printf("%d ", n % 2);
+    if (n / 2 != 0) {
+        recurse(n / 2);
+    } else {
+        printf("\n");
+    }
+}
+
+recurse(13); 
+```
+
+. . .
+
+```C
+binaire(13): n = 13, n % 2 = 1, n / 2 = 6,
+    binaire(6): n = 6, n % 2 = 0, n / 2 = 3,
+        binaire(3): n = 3, n % 2 = 1, n / 2 = 1,
+            binaire(1): n = 1, n % 2 = 1, n / 2 = 0.
+
+// affiche: 1 1 0 1
+```
+
+# Exercice: réusinage et récursivité (1/4)
+
+## Réusiner le code du PGCD avec une fonction récursive
+
+## Étudier l'exécution
+
+```C
+42 = 27 * 1 + 15
+27 = 15 * 1 + 12
+15 = 12 * 1 + 3
+12 = 3  * 4 + 0
+```
+
+# Exercice: réusinage et récursivité (2/4)
+
+## Réusiner le code du PGCD avec une fonction récursive
+
+## Étudier l'exécution
+
+```C
+42 = 27 * 1 + 15   |   PGCD(42, 27) 
+27 = 15 * 1 + 12   |   PGCD(27, 15) 
+15 = 12 * 1 +  3   |   PGCD(15, 12) 
+12 =  3 * 4 +  0   |   PGCD(12,  3) 
+```
+
+# Exercice: réusinage et récursivité (3/4)
+
+## Réusiner le code du PGCD avec une fonction récursive
+
+## Étudier l'exécution
+
+```C
+42 = 27 * 1 + 15   |   PGCD(42, 27) 
+27 = 15 * 1 + 12   |   PGCD(27, 15) 
+15 = 12 * 1 +  3   |   PGCD(15, 12) 
+12 =  3 * 4 +  0   |   PGCD(12,  3) 
+```
+
+## Effectuer l'empilage - dépilage
+
+. . .
+
+```C
+PGCD(12,  3)    |     3
+PGCD(15, 12)    |     3
+PGCD(27, 15)    |     3
+PGCD(42, 27)    |     3
+```
+
+# Exercice: réusinage et récursivité (4/4)
+
+## Écrire le code
+
+. . .
+
+```C
+int pgcd(int n, int m) {
+    if (n % m > 0) {
+        return pgcd(m, n % m);
+    } else {
+        return m;
+    }
+}
+```
 
-<!-- ## Nombres à virgule flottante, simple/double précision -->
+# Exercices pour les semaines sans cours
 
+## Quelques algorithmes à réaliser et poster sur matrix
 
-# TODO jusqu'aux vacances
+1. Algorithme du PPCM.
+2. La puissance indienne.
+3. La suite de Fibonacci.
 
-* Refactorisation
-* Tris et complexité
-* Récursivité
-- 
GitLab