From 407b3f890533d5cfe23eff0bc7c647957f078563 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Sun, 13 Oct 2024 21:00:19 +0200
Subject: [PATCH] update 2024

---
 slides/cours_4.md |  61 -----
 slides/cours_5.md | 480 +++++++++++++++++++----------------
 slides/cours_6.md | 633 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 890 insertions(+), 284 deletions(-)
 create mode 100644 slides/cours_6.md

diff --git a/slides/cours_4.md b/slides/cours_4.md
index 15e37dd..f018ab2 100644
--- a/slides/cours_4.md
+++ b/slides/cours_4.md
@@ -208,64 +208,3 @@ Algorithme de génération de nombres premiers.
 
 * Implémenter l'algorithme et le poster sur le salon `Element`.
 
-# Crible d'Ératosthène: solution
-
-\footnotesize
-
-```C
-#include <stdio.h>
-#include <stdbool.h>
-#define SIZE 51
-int main() {
-   bool tab[SIZE];
-   for (int i=0;i<SIZE;i++) {
-      tab[i] = true;  
-   }
-   for (int i = 2; i < SIZE; i++) {
-      if (tab[i]) {
-         printf("%d ", i);
-         int j = i;
-         while (j < SIZE) {
-            j += i;
-            tab[j] = false;
-         } 
-      } 
-   }
-   printf("\n");
-}
-```
-
-
-# Réusinage de code (refactoring)
-
-## Le réusinage est?
-
-. . .
-
-* le processus de restructuration d'un programme:
-    * en modifiant son design,
-    * en modifiant sa structure,
-    * en modifiant ses algorithmes
-    * mais en **conservant ses fonctionalités**.
-
-. . .
-
-## Avantages?
-
-. . .
-
-* Amélioration de la lisibilité,
-* Amélioration de la maintenabilité,
-* Réduction de la complexité.
-
-. . .
-
-## "Make it work, make it nice, make it fast",  Kent Beck.
-
-. . .
-
-## Exercice:
-
-* Réusiner le code se trouvant sur
-  [Cyberlearn](https://cyberlearn.hes-so.ch/pluginfile.php/703384/mod_resource/content/1/comprendre.c).
-
diff --git a/slides/cours_5.md b/slides/cours_5.md
index 5b60503..026299a 100644
--- a/slides/cours_5.md
+++ b/slides/cours_5.md
@@ -1,15 +1,77 @@
 ---
-title: "Tableaux à deux dimensions et représentation des nombres"
+title: "Tableaux à deux dimensions et récursivité"
 date: "2024-10-14"
 ---
 
+# Rappel / devoirs: Crible d'Ératosthène
+
+* But: 
+    - Générer tous les nombres premiers plus petit qu'un entier $N$.
+    - En utilisant qu'un tableau de booléens
+    - Et que des multiplications
+* Exercice: Écrire l'algorithme en C.
+
+# Crible d'Ératosthène: solution
+
+\footnotesize
+
+```C
+#include <stdio.h>
+#include <stdbool.h>
+#define SIZE 51
+int main() {
+   bool tab[SIZE];
+   for (int i=0;i<SIZE;i++) {
+      tab[i] = true;  
+   }
+   for (int i = 2; i < SIZE; i++) {
+      if (tab[i]) {
+         printf("%d ", i);
+         int j = i;
+         while (j < SIZE) {
+            j += i;
+            tab[j] = false;
+         } 
+      } 
+   }
+   printf("\n");
+}
+```
+
 # Réusinage de code (refactoring)
 
+## Le réusinage est?
+
+. . .
+
+* le processus de restructuration d'un programme:
+    * en modifiant son design,
+    * en modifiant sa structure,
+    * en modifiant ses algorithmes
+    * mais en **conservant ses fonctionalités**.
+
+. . .
+
+## Avantages?
+
+. . .
+
+* Amélioration de la lisibilité,
+* Amélioration de la maintenabilité,
+* Réduction de la complexité.
+
+. . .
+
+## "Make it work, make it nice, make it fast",  Kent Beck.
+
+. . .
+
 ## Exercice:
 
 * Réusiner le code se trouvant sur
   [Cyberlearn](https://cyberlearn.hes-so.ch/pluginfile.php/703384/mod_resource/content/1/comprendre.c).
 
+
 # Tableau à deux dimensions (1/4)
 
 ## Mais qu'est-ce donc?
@@ -175,313 +237,285 @@ for (int i = 0; i < NX; ++i) {
 
 A faire à la maison comme exercice!
 
-# Représentation des nombres (1/2)
+# And now for something completely different
 
-* Le nombre `247`.
+\Huge La récursivité
 
-## Nombres décimaux: Les nombres en base 10 
+# La factorielle: Code impératif
 
-+--------+--------+--------+
-| $10^2$ | $10^1$ | $10^0$ |
-+--------+--------+--------+
-| `2`    | `4`    | `7`    |
-+--------+--------+--------+
+* Code impératif
 
-$$
-247 = 2\cdot 10^2 + 4\cdot 10^1 + 7\cdot 10^0.
-$$
-
-# Représentation des nombres (2/2)
+```C
+int factorial(int n) {
+    int f = 1;
+    for (int i = 1; i < n; ++i) {
+        f *= i;
+    }
+    return f;
+}
+```
 
-* Le nombre `11110111`.
+# Exemple de récursivité (1/2)
 
-## Nombres binaires: Les nombres en base 2
+## La factorielle
 
-+-------+-------+-------+-------+-------+-------+-------+-------+
-| $2^7$ | $2^6$ | $2^5$ | $2^4$ | $2^3$ | $2^2$ | $2^1$ | $2^0$ |
-+-------+-------+-------+-------+-------+-------+-------+-------+
-| `1`   | `1`   | `1`   | `1`   | `0`   | `1`   | `1`   | `1`   |
-+-------+-------+-------+-------+-------+-------+-------+-------+
- 
-$$
-1\cdot 2^7 + 1\cdot 2^6 +1\cdot 2^5 +1\cdot 2^4 +0\cdot 2^3 +1\cdot 2^2
-+1\cdot 2^1 +1\cdot 2^0
-$$
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
+    }
+}
+```
 
 . . .
 
-$$
-= 247.
-$$
-
-# Conversion de décimal à binaire (1/2)
-
-## Convertir 11 en binaire?
+## Que se passe-t-il quand on fait `factorial(4)`?
 
 . . .
 
-* On décompose en puissances de 2 en partant de la plus grande possible
+## On empile les appels
 
-    ```
-    11 / 8 = 1, 11 % 8 = 3
-    3  / 4 = 0,  3 % 4 = 3
-    3  / 2 = 1,  3 % 2 = 1
-    1  / 1 = 1,  1 % 1 = 0
-    ```
-* On a donc
-
-    $$
-    1011 \Rightarrow 1\cdot 2^3 + 0\cdot 2^2 + 1\cdot 2^1 + 1\cdot
-    2^0=11.
-    $$
++----------------+----------------+----------------+----------------+
+|                |                |                | `factorial(1)` |
++----------------+----------------+----------------+----------------+
+|                |                | `factorial(2)` | `factorial(2)` |
++----------------+----------------+----------------+----------------+
+|                | `factorial(3)` | `factorial(3)` | `factorial(3)` |
++----------------+----------------+----------------+----------------+
+| `factorial(4)` | `factorial(4)` | `factorial(4)` | `factorial(4)` |
++----------------+----------------+----------------+----------------+
 
-# Conversion de décimal à binaire (2/2)
+# Exemple de récursivité (2/2)
 
-## Convertir un nombre arbitraire en binaire: 247?
+## La factorielle
 
-* Par groupe établir un algorithme.
-
-. . .
-
-## Algorithme
-
-1. Initialisation
-    
-    ```C
-    num = 247
-    N = 0
-
-    tant que (2^(N+1) < num) {
-        N += 1
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
     }
-    ```
+}
+```
 
 . . .
 
-2. Boucle
+## Que se passe-t-il quand on fait `factorial(4)`?
 
-    ```C
-    tant que (N >= 0) {
-        bit = num / 2^N
-        num = num % 2^N
-        N -= 1
-    }
-    ```
-
-# Les additions en binaire
+. . .
 
-Que donne l'addition `1101` avec `0110`?
+## On dépile les calculs
 
-* L'addition est la même que dans le système décimal
++----------------+----------------+----------------+----------------+
+|  `1`           |                |                |                |
++----------------+----------------+----------------+----------------+
+| `factorial(2)` |  `2 * 1 = 2`   |                |                |
++----------------+----------------+----------------+----------------+
+| `factorial(3)` | `factorial(3)` |  `3 * 2 = 6`   |                |
++----------------+----------------+----------------+----------------+
+| `factorial(4)` | `factorial(4)` | `factorial(4)` |  `4 * 6 = 24`  |
++----------------+----------------+----------------+----------------+
 
-    ```
-       1101         8+4+0+1 = 13
-    +  0110    +    0+4+2+0 =  6
-    -------    -----------------
-      10011      16+0+0+2+1 = 19
-    ```
-* Les entiers sur un ordinateur ont une précision **fixée** (ici 4 bits).
-* Que se passe-t-il donc ici?
+# La récursivité (1/4)
 
-. . .
+## Formellement 
 
-## Dépassement de capacité: le nombre est "tronqué"
+* Une condition de récursivité - qui *réduit* les cas successifs vers...
+* Une condition d'arrêt - qui retourne un résultat
 
-* `10011 (19) -> 0011 (3)`.
-* On fait "le tour"."
+## Pour la factorielle, qui est qui?
 
-# Entier non-signés minimal/maximal
+```C
+int factorial(int n) {
+    if (n > 1) {
+        return n * factorial(n - 1);
+    } else {
+        return 1;
+    }
+}
+```
 
-* Quel est l'entier non-signé maximal représentable avec 4 bit?
+# La récursivité (2/4)
 
-. . .
+## Formellement 
 
-$$
-(1111)_2 = 8+4+2+1 = 15
-$$
+* Une condition de récursivité - qui *réduit* les cas successifs vers...
+* Une condition d'arrêt - qui retourne un résultat
 
-* Quel est l'entier non-signé minimal représentable avec 4 bit?
+## 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;
+    }
+}
+```
 
-$$
-(0000)_2 = 0+0+0+0 = 0
-$$
+# La récursivité (3/4)
 
-* Quel est l'entier non-signé min/max représentable avec N bit?
+## Exercice: trouver l'$\varepsilon$-machine pour un `double`
 
 . . .
 
-$$
-0\mbox{ et  }2^N-1.
-$$
-
-* Donc `uint32_t?` maximal est?
+Rappelez-vous vous l'avez fait en style **impératif** plus tôt.
 
 . . .
 
-$$
-2^{32}-1=4'294'967'295
-$$
-
-
-# Les multiplications en binaire (1/2)
-
-Que donne la multiplication de `1101` avec `0110`?
+```C
+double epsilon_machine(double eps) {
+    if (1.0 + eps != 1.0) {
+        return epsilon_machine(eps / 2.0);
+    } else {
+        return eps;
+    }
+}
+```
 
-* La multiplication est la même que dans le système décimal
+# La récursivité (4/4)
 
-    ```
-         1101                13
-    *    0110    *            6
-    ---------    --------------
-         0000                78
-        11010
-       110100
-    + 0000000
-    ---------    --------------
-      1001110    64+0+0+8+4+2+0
-    ```
+\footnotesize
 
-# Les multiplications en binaire (2/2)
+## Exercice: que fait ce code récursif?
 
-## Que fait la multiplication par 2?
+```C
+void recurse(int n) {
+    printf("%d ", n % 2);
+    if (n / 2 != 0) {
+        recurse(n / 2);
+    } else {
+        printf("\n");
+    }
+}
+recurse(13); 
+```
 
 . . .
 
-* Décalage de un bit vers la gauche!
-
-    ```
-         0110
-    *    0010
-    ---------
-         0000
-    +   01100
-    ---------
-        01100
-    ```
-
-. . .
+```C
+recurse(13): n = 13, n % 2 = 1, n / 2 = 6,
+    recurse(6): n = 6, n % 2 = 0, n / 2 = 3,
+        recurse(3): n = 3, n % 2 = 1, n / 2 = 1,
+            recurse(1): n = 1, n % 2 = 1, n / 2 = 0.
 
-## Que fait la multiplication par $2^N$?
+// affiche: 1 1 0 1
+```
 
 . . .
 
-* Décalage de $N$ bits vers la gauche!
+Affiche la représentation binaire d'un nombre!
 
-# Entiers signés (1/2)
+# Exercice: réusinage et récursivité (1/4)
 
-Pas de nombres négatifs encore...
+## Réusiner le code du PGCD avec une fonction récursive
 
-## Comment faire?
+## Étudier l'exécution
 
-. . .
-
-## Solution naïve:
-
-* On ajoute un bit de signe (le bit de poids fort):
-
-    ```
-    00000010: +2
-    10000010: -2
-    ```
-
-## Problèmes?
+```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)
 
-* Il y a deux zéros (pas trop grave): `10000000` et `00000000`
-* Les additions différentes que pour les non-signés (très grave)
-    
-    ```
-      00000010              2    
-    + 10000100           + -4
-    ----------           ----
-      10000110 = -6  !=    -2
-    ```
+## Réusiner le code du PGCD avec une fonction récursive
 
-# Entiers signés (2/2)
+## Étudier l'exécution
 
-## Beaucoup mieux
+```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) 
+```
 
-* Complément à un:
-    * on inverse tous les bits: `1001 => 0110`.
+# Exercice: réusinage et récursivité (3/4)
 
-## Encore un peu mieux
+## Réusiner le code du PGCD avec une fonction récursive
 
-* Complément à deux:
-    * on inverse tous les bits,
-    * on ajoute 1 (on ignore les dépassements).
+## É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) 
+```
 
-* Comment écrit-on `-4` en 8 bits?
+## Effectuer l'empilage - dépilage
 
 . . .
 
+```C
+PGCD(12,  3)    |     3
+PGCD(15, 12)    |     3
+PGCD(27, 15)    |     3
+PGCD(42, 27)    |     3
 ```
-     4 =  00000100
-            ________
-    -4 =>   00000100
-            
-            11111011
-          + 00000001 
-          ----------
-            11111100
-```
-
-# Le complément à 2 (1/2)
 
-## Questions:
+# Exercice: réusinage et récursivité (4/4)
 
-* Comment on écrit `+0` et `-0`?
-* Comment calcule-t-on `2 + (-4)`?
-* Quel est le complément à 2 de `1000 0000`?
+## Écrire le code
 
 . . .
 
-## Réponses
-
-* Comment on écrit `+0` et `-0`?
-
-    ```
-    +0 = 00000000
-    -0 = 11111111 + 00000001 = 100000000 => 00000000 
-    ```
-* Comment calcule-t-on `2 + (-4)`?
+```C
+int pgcd(int n, int m) {
+    if (n % m > 0) {
+        return pgcd(m, n % m);
+    } else {
+        return m;
+    }
+}
+```
 
-    ```
-      00000010            2
-    + 11111100        +  -4
-    ----------        -----
-      11111110           -2
-    ```
-* En effet
+# La suite de Fibonacci (1/2)
 
-    ```
-    11111110 => 00000001 + 00000001 = 00000010 = 2.
-    ```
+## Règle
 
-# Le complément à 2 (2/2)
+$$
+\mathrm{Fib}(n) = \mathrm{Fib}(n-1) + \mathrm{Fib}(n-2),\quad
+\mathrm{Fib}(0)=0,\quad \mathrm{Fib}(1)=1.
+$$
 
-## Quels sont les entiers représentables en 8 bits?
+## Exercice: écrire la fonction $\mathrm{Fib}$ en récursif et impératif
 
 . . .
 
-```
-01111111 =>  127
-10000000 => -128 // par définition
-```
+## En récursif (6 lignes)
 
-## Quels sont les entiers représentables sur $N$ bits?
+```C
+int fib(int n) {
+    if (n > 1) {
+        return fib(n - 1) + fib(n - 2);
+    } 
+    return n;
+}
+```
 
-. . .
+# La suite de Fibonacci (2/2)
 
-$$
--2^{N-1} ... 2^{N-1}-1.
-$$
+## Et en impératif (11 lignes)
 
-## Remarque: dépassement de capacité en `C`
+```C
+int fib_imp(int n) {
+    int fib0 = 1;
+    int fib1 = 1;
+    int fib  = n == 0 ? 0 : fib1;
+    for (int i = 2; i < n; ++i) {
+        fib  = fib0 + fib1;
+        fib0 = fib1;
+        fib1 = fib;
+    }
+    return fib;
+}
+```
 
-* Comportement indéfini!
 
diff --git a/slides/cours_6.md b/slides/cours_6.md
new file mode 100644
index 0000000..748b6e2
--- /dev/null
+++ b/slides/cours_6.md
@@ -0,0 +1,633 @@
+---
+title: "Représentation des nombres"
+date: "2024-10-14"
+---
+
+# Représentation des nombres
+
+\Huge La représentation des nombres
+
+# Représentation des nombres (1/2)
+
+* Le nombre `247`.
+
+## Nombres décimaux: Les nombres en base 10 
+
++--------+--------+--------+
+| $10^2$ | $10^1$ | $10^0$ |
++--------+--------+--------+
+| `2`    | `4`    | `7`    |
++--------+--------+--------+
+
+$$
+247 = 2\cdot 10^2 + 4\cdot 10^1 + 7\cdot 10^0.
+$$
+
+# Représentation des nombres (2/2)
+
+* Le nombre `11110111`.
+
+## Nombres binaires: Les nombres en base 2
+
++-------+-------+-------+-------+-------+-------+-------+-------+
+| $2^7$ | $2^6$ | $2^5$ | $2^4$ | $2^3$ | $2^2$ | $2^1$ | $2^0$ |
++-------+-------+-------+-------+-------+-------+-------+-------+
+| `1`   | `1`   | `1`   | `1`   | `0`   | `1`   | `1`   | `1`   |
++-------+-------+-------+-------+-------+-------+-------+-------+
+ 
+$$
+1\cdot 2^7 + 1\cdot 2^6 +1\cdot 2^5 +1\cdot 2^4 +0\cdot 2^3 +1\cdot 2^2
++1\cdot 2^1 +1\cdot 2^0
+$$
+
+. . .
+
+$$
+= 247.
+$$
+
+# Conversion de décimal à binaire (1/2)
+
+## Convertir 11 en binaire?
+
+. . .
+
+* On décompose en puissances de 2 en partant de la plus grande possible
+
+    ```
+    11 / 8 = 1, 11 % 8 = 3
+    3  / 4 = 0,  3 % 4 = 3
+    3  / 2 = 1,  3 % 2 = 1
+    1  / 1 = 1,  1 % 1 = 0
+    ```
+* On a donc
+
+    $$
+    1011 \Rightarrow 1\cdot 2^3 + 0\cdot 2^2 + 1\cdot 2^1 + 1\cdot
+    2^0=11.
+    $$
+
+# Conversion de décimal à binaire (2/2)
+
+## Convertir un nombre arbitraire en binaire: 247?
+
+* Par groupe établir un algorithme.
+
+. . .
+
+## Algorithme
+
+1. Initialisation
+    
+    ```C
+    num = 247
+    N = 0
+
+    tant que (2^(N+1) < num) {
+        N += 1
+    }
+    ```
+
+. . .
+
+2. Boucle
+
+    ```C
+    tant que (N >= 0) {
+        bit = num / 2^N
+        num = num % 2^N
+        N -= 1
+    }
+    ```
+
+# Les additions en binaire
+
+Que donne l'addition `1101` avec `0110`?
+
+* L'addition est la même que dans le système décimal
+
+    ```
+       1101         8+4+0+1 = 13
+    +  0110    +    0+4+2+0 =  6
+    -------    -----------------
+      10011      16+0+0+2+1 = 19
+    ```
+* Les entiers sur un ordinateur ont une précision **fixée** (ici 4 bits).
+* Que se passe-t-il donc ici?
+
+. . .
+
+## Dépassement de capacité: le nombre est "tronqué"
+
+* `10011 (19) -> 0011 (3)`.
+* On fait "le tour"."
+
+# Entier non-signés minimal/maximal
+
+* Quel est l'entier non-signé maximal représentable avec 4 bit?
+
+. . .
+
+$$
+(1111)_2 = 8+4+2+1 = 15
+$$
+
+* Quel est l'entier non-signé minimal représentable avec 4 bit?
+
+. . .
+
+$$
+(0000)_2 = 0+0+0+0 = 0
+$$
+
+* Quel est l'entier non-signé min/max représentable avec N bit?
+
+. . .
+
+$$
+0\mbox{ et  }2^N-1.
+$$
+
+* Donc `uint32_t?` maximal est?
+
+. . .
+
+$$
+2^{32}-1=4'294'967'295
+$$
+
+
+# Les multiplications en binaire (1/2)
+
+Que donne la multiplication de `1101` avec `0110`?
+
+* La multiplication est la même que dans le système décimal
+
+    ```
+         1101                13
+    *    0110    *            6
+    ---------    --------------
+         0000                78
+        11010
+       110100
+    + 0000000
+    ---------    --------------
+      1001110    64+0+0+8+4+2+0
+    ```
+
+# Les multiplications en binaire (2/2)
+
+## Que fait la multiplication par 2?
+
+. . .
+
+* Décalage de un bit vers la gauche!
+
+    ```
+         0110
+    *    0010
+    ---------
+         0000
+    +   01100
+    ---------
+        01100
+    ```
+
+. . .
+
+## Que fait la multiplication par $2^N$?
+
+. . .
+
+* Décalage de $N$ bits vers la gauche!
+
+# Entiers signés (1/2)
+
+Pas de nombres négatifs encore...
+
+## Comment faire?
+
+. . .
+
+## Solution naïve:
+
+* On ajoute un bit de signe (le bit de poids fort):
+
+    ```
+    00000010: +2
+    10000010: -2
+    ```
+
+## Problèmes?
+
+. . .
+
+* Il y a deux zéros (pas trop grave): `10000000` et `00000000`
+* Les additions différentes que pour les non-signés (très grave)
+    
+    ```
+      00000010              2    
+    + 10000100           + -4
+    ----------           ----
+      10000110 = -6  !=    -2
+    ```
+
+# Entiers signés (2/2)
+
+## Beaucoup mieux
+
+* Complément à un:
+    * on inverse tous les bits: `1001 => 0110`.
+
+## Encore un peu mieux
+
+* Complément à deux:
+    * on inverse tous les bits,
+    * on ajoute 1 (on ignore les dépassements).
+
+. . .
+
+* Comment écrit-on `-4` en 8 bits?
+
+. . .
+
+```
+     4 =  00000100
+            ________
+    -4 =>   00000100
+            
+            11111011
+          + 00000001 
+          ----------
+            11111100
+```
+
+# Le complément à 2 (1/2)
+
+## Questions:
+
+* Comment on écrit `+0` et `-0`?
+* Comment calcule-t-on `2 + (-4)`?
+* Quel est le complément à 2 de `1000 0000`?
+
+. . .
+
+## Réponses
+
+* Comment on écrit `+0` et `-0`?
+
+    ```
+    +0 = 00000000
+    -0 = 11111111 + 00000001 = 100000000 => 00000000 
+    ```
+* Comment calcule-t-on `2 + (-4)`?
+
+    ```
+      00000010            2
+    + 11111100        +  -4
+    ----------        -----
+      11111110           -2
+    ```
+* En effet
+
+    ```
+    11111110 => 00000001 + 00000001 = 00000010 = 2.
+    ```
+
+# Le complément à 2 (2/2)
+
+## Quels sont les entiers représentables en 8 bits?
+
+. . .
+
+```
+01111111 =>  127
+10000000 => -128 // par définition
+```
+
+## Quels sont les entiers représentables sur $N$ bits?
+
+. . .
+
+$$
+-2^{N-1} ... 2^{N-1}-1.
+$$
+
+## Remarque: dépassement de capacité en `C`
+
+* Comportement indéfini!
+
+
+# Nombres à virgule (1/3)
+
+## Comment manipuler des nombres à virgule?
+
+$$
+0.1 + 0.2 = 0.3.
+$$
+
+Facile non?
+
+. . .
+
+## Et ça?
+
+```C
+#include <stdio.h>
+#include <stdlib.h>
+int main(int argc, char *argv[]) {
+    float a = atof(argv[1]);
+    float b = atof(argv[2]);
+    printf("%.10f\n", (double)(a + b));
+}
+```
+
+. . .
+
+## Que se passe-t-il donc?
+
+# Nombres à virgule (2/3)
+
+## Nombres à virgule fixe
+
++-------+-------+-------+-------+-----+----------+----------+----------+----------+
+| $2^3$ | $2^2$ | $2^1$ | $2^0$ | `.` | $2^{-1}$ | $2^{-2}$ | $2^{-3}$ | $2^{-4}$ |
++-------+-------+-------+-------+-----+----------+----------+----------+----------+
+| `1`   | `0`   | `1`   |  `0`  | `.` | `0`      | `1`      | `0`      | `1`      |
++-------+-------+-------+-------+-----+----------+----------+----------+----------+
+
+## Qu'est-ce ça donne en décimal?
+
+. . .
+
+$$
+2^3+2^1+\frac{1}{2^2}+\frac{1}{2^4} = 8+2+0.5+0.0625=10.5625.
+$$
+
+## Limites de cette représentation? 
+
+. . .
+
+
+* Tous les nombres `> 16`.
+* Tous les nombres `< 0.0625`.
+* Tous les nombres dont la décimale est pas un multiple de `0.0625`.
+
+# Nombres à virgule (3/3)
+
+## Nombres à virgule fixe
+
+* Nombres de $0=0000.0000$ à $15.9375=1111.1111$.
+* Beaucoup de "trous" (au moins $0.0625$) entre deux nombres.
+
+## Solution partielle?
+
+. . .
+
+* Rajouter des bits.
+* Bouger la virgule.
+
+# Nombres à virgule flottante (1/2)
+
+## Notation scientifique
+
+* Les nombres sont représentés en terme:
+    * Une mantisse
+    * Une base
+    * Un exposant
+
+$$
+\underbrace{22.1214}_{\mbox{nombre}}=\underbrace{221214}_{\mbox{mantisse}}\cdot
+{\underbrace{10}_{\mbox{base}}}{\overbrace{^{-4}}^{\mbox{exp.}}},
+$$
+
+. . .
+
+On peut donc séparer la représentation en 2:
+
+* La mantisse
+* L'exposant
+
+# Nombres à virgule flottante (2/2)
+
+## Quel est l'avantage?
+
+. . .
+
+On peut représenter des nombres sur énormément d'ordres de grandeur avec un
+nombre de bits fixés.
+
+## Différence fondamentale avec la virgule fixe?
+
+. . .
+
+La précision des nombres est **variable**:
+
+* On a uniquement un nombre de chiffres **significatifs**.
+$$
+123456\cdot 10^{23}+ 123456\cdot 10^{-23}.
+$$
+
+## Quel inconvénient y a-t-il?
+
+. . .
+
+Ce mélange d'échelles entraîne un **perte de précision**.
+
+# Nombres à virgule flottante simple précision (1/4)
+
+Aussi appelés *IEEE 754 single-precision binary floating point*.
+
+![Nombres à virgule flottante 32 bits. Source:
+[Wikipedia](https://en.wikipedia.org/wiki/Single-precision_floating-point_format)](figs/Float_example_bare.svg)
+
+## Spécification
+
+* 1 bit de signe,
+* 8 bits d'exposant,
+* 23 bits de mantisse.
+
+$$
+(-1)^{b_{31}}\cdot 2^{(b_{30}b_{29}\dots b_{23})_{2}-127}\cdot (1.b_{22}b_{21}\dots b_{0})_{2},
+$$
+
+## Calculer la valeur décimale du nombre ci-dessus
+
+# 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)](figs/Float_example.svg)
+
+. . .
+
+\begin{align}
+\mbox{exposant}&=\sum_{i=0}^7 b_{23+i}2^i=2^2+2^3+2^4+2^5+2^6=124-127,\\
+\mbox{mantisse}&=1+\sum_{i=1}^{23}b_{23-i}2^{-i}=1+2^{-2}=1.25,\\
+&\Rightarrow (-1)^0\cdot 2^{-3}\cdot 1.25=0.15625
+\end{align}
+
+# Nombres à virgule flottante simple précision (3/4)
+
+## Quel nombre ne peux pas être vraiment représenté?
+
+. . .
+
+## Zéro: exception pour l'exposant
+
+* Si l'exposant est `00000000` (zéro)
+$$
+(-1)^{\mbox{sign}}\cdot 2^{-126}\cdot 0.\mbox{mantisse},
+$$
+* Sinon si l'exposant est `00000001` à `11111110`
+$$
+\mbox{valeur normale},
+$$
+* Sinon `11111111` donne `NaN`.
+
+# Nombres à virgule flottante simple précision (4/4)
+
+## Quels sont les plus petits/grands nombres positifs représentables?
+
+. . .
+
+\begin{align}
+0\ 0\dots0\ 0\dots01&=2^{-126}\cdot 2^{-23}=1.4...\cdot
+10^{-45},\\
+0\ 1\dots10\ 1\dots1&=2^{127}\cdot (2-2^{-23})=3.4...\cdot
+10^{38}.
+\end{align}
+
+## Combien de chiffres significatifs en décimal?
+
+. . .
+
+* 24 bits ($23 + 1$) sont utiles pour la mantisse, soit $2^{24}-1$:
+    * La mantisse fait $\sim2^{24}\sim 10^7$,
+    * Ou encore $\sim \log_{10}(2^{24})\sim 7$.
+* Environ **sept** chiffres significatifs.
+
+# Nombres à virgule flottante double précision (64bits)
+
+## Spécification
+
+* 1 bit de signe,
+* 11 bits d'exposant,
+* 52 bits de mantisse.
+
+. . .
+
+## Combien de chiffres significatifs?
+
+* La mantisse fait $\sim 2^{53}\sim10^{16}$,
+* Ou encore $\sim \log_{10}(2^{53})\sim 16$,
+* Environ **seize** chiffres significatifs.
+
+## Plus petit/plus grand nombre représentable?
+
+. . .
+
+* Plus petite mantisse et exposant: $\sim 2^{-52}\cdot 2^{-1022}\sim 4\cdot 10^{-324}$,
+* Plus grande mantisse et exposant: $\sim 2\cdot 2^{1023}\sim \cdot 1.8\cdot 10^{308}$.
+
+# Précision finie (1/3)
+
+## Erreur de représentation
+
+* Les nombres réels ont potentiellement un **nombre infini** de décimales
+    * $1/3=0.\overline{3}$,
+    * $\pi=3.1415926535...$.
+* Les nombres à virgule flottante peuvent en représenter qu'un **nombre
+  fini**.
+  * $1/3\cong 0.33333$, erreur $0.00000\overline{3}$.
+  * $\pi\cong3.14159$, erreur $0.0000026535...$.
+
+On rencontre donc des **erreurs de représentation** ou **erreurs
+d'arrondi**.
+
+. . .
+    
+## Et quand on calcule?
+
+* Avec deux chiffres significatifs
+\begin{align}
+&8.9+(0.02+0.04)=8.96=9.0,\\
+&(8.9+0.02)+0.04=8.9+0.04=8.9.
+\end{align}
+
+. . .
+
+## Même pas associatif!
+
+# Précision finie (2/3)
+
+## Erreur de représentation virgule flottante
+
+$$
+(1.2)_{10} = 1.\overline{0011}\cdot 2^0\Rightarrow 0\ 01111111\
+00110011001100110011010.
+$$
+Erreur d'arrondi dans les deux derniers bits et tout ceux qui viennent
+ensuite
+$$
+\varepsilon_2 = (00000000000000000000011)_2.
+$$
+Ou en décimal
+$$
+\varepsilon_{10} = 4.76837158203125\cdot 10^{-8}.
+$$
+
+# Précision finie (3/3)
+
+## Comment définir l'égalité de 2 nombres à virgule flottante?
+
+. . .
+
+Ou en d'autres termes, pour quel $\varepsilon>0$ (appelé `epsilon-machine`) on a
+$$
+1+\varepsilon = 1,
+$$
+pour un nombre à virgule flottante?
+
+. . .
+
+Pour un `float` (32 bits) la différence est à 
+$$
+2^{-23}=1.19\cdot 10^{-7},
+$$
+Soit la précision de la mantisse.
+
+## Comment le mesurer (par groupe)?
+
+. . .
+
+```C
+float eps = 1.0;
+while ((float)1.0 + (float)0.5 * eps != (float)1.0) {
+    eps = (float)0.5 * eps;
+}
+printf("eps = %g\n", eps);
+```
+
+# Erreurs d'arrondi
+
+Et jusqu'ici on a encore pas fait d'arithmétique!
+
+## Multiplication avec deux chiffres significatifs, décimal
+
+$$
+(1.1)_{10}\cdot (1.1)_{10}=(1.21)_{10}=(1.2)_{10}.
+$$
+En continuant ce petit jeu:
+$$
+\underbrace{1.1\cdot 1.1\cdots 1.1}_{\mbox{10 fois}}=2.0.
+$$
+Alors qu'en réalité
+$$
+1.1^{10}=2.5937...
+$$
+Soit une erreur de près de 1/5e!
+
+. . .
+
+## Le même phénomène se produit (à plus petite échelle) avec les `float` ou `double`.
+
-- 
GitLab