From 9fbada0a9752f7b0b32ed61514957b59d80aeb43 Mon Sep 17 00:00:00 2001 From: Orestis <orestis.malaspinas@pm.me> Date: Mon, 18 Oct 2021 21:28:20 +0200 Subject: [PATCH] =?UTF-8?q?fin=20choses=20=C3=A0=20dire=20sur=20floating?= =?UTF-8?q?=20points?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slides/cours_5.md | 77 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/slides/cours_5.md b/slides/cours_5.md index f92cb19..8de07ce 100644 --- a/slides/cours_5.md +++ b/slides/cours_5.md @@ -206,7 +206,7 @@ Que donne la multiplication de `1101` avec `0110`? . . . -* Décalade de $N$ bits vers la gauche! +* Décalage de $N$ bits vers la gauche! # Entiers signés (1/2) @@ -534,7 +534,7 @@ $$ * 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 +# Précision finie (1/3) ## Erreur de représentation @@ -554,7 +554,6 @@ 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. @@ -564,9 +563,79 @@ d'arrondi**. ## Même pas associatif! -# Erreurs d'arrondi +# 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$ 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 (1/N) + +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`. <!-- # TODO -- -- GitLab