Nombres à virgule flottante
Les équations sur ce site sont affichées avec MathJax.

Merci à Julia Evans
Manipuler efficacement et correctement les nombres à virgule flottante
est une chose bien plus périlleuse qu'il n'y paraît à première
vue, et dont les périls échappent à bien des gens. À
ce sujet :
- Comment implémenter une fonction générique
assez_proches() (une manière parmi d'autres d'y arriver, évidemment)
pour comparer deux nombres, à virgule flottante ou non, avec
== s'ils ont une représentation exacte et sur la base d'une
tolérance à l'erreur (un ) dans le cas contraire :
Assez-proches.html
Aussi, quelques articles :
- Un historique du standard
IEEE 754 :
http://www.eecs.berkeley.edu/~wkahan/ieee754status/754story.html
- Ce qu'est un NaN, pour Not a Number :
http://en.wikipedia.org/wiki/NaN
- Une explication claire des raisons pour lesquelles
0.1 + 0.2 != 0.3 :
http://0.30000000000000004.com/
- Une alternative à
IEEE 754?
Présentation de John L. Gustafson en 2013 sur
« unum » :
http://sites.ieee.org/scv-cs/files/2013/03/Right-SizingPrecision1.pdf
- En 2014, Christian Plesner Hansen explique pourquoi il trouve
IEEE 754 frustrant
(indice : le texte porte beaucoup sur la question de la propriété
intellectuelle) :
http://h14s.p5r.org/2014/11/why-i-find-ieee-754-frustrating.html
- À propos du
matériel, limite de la précision physique des calculs lorsque
ceux-ci sont supportés par le substrat matériel : http://en.wikipedia.org/wiki/Machine_epsilon
- Présentation générale sur les nombres à virgule flottante, par Florent de
Dinechin en 2004 :
http://lipforge.ens-lyon.fr/www/crlibm/documents/cern.pdf
- Texte fouillé et très riche sur tout ce qu'une programmeuse
ou un programmeur devrait savoir sur les nombres à virgule flottante :
- À propos des périls de l'approximation (arrondissement) des
nombres à virgule flottante, par Dan Clarke en
2006 : http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
- À propos de la propagation des erreurs lors de calculs sur des nombres à
virgule flottante, texte de 2013 par Liyuan Gao :
http://www.phailed.me/2013/05/introduction-to-scientific-computing-error-propagation/
- À propos de la difficulté de convertir certains nombres entiers
en une représentation à virgule flottante, par Rick Regan en
2010 : http://www.exploringbinary.com/decimal-to-floating-point-needs-arbitrary-precision/
- Pourquoi n'utilise-t-on pas de nombres à virgule flottante dans les
applications financières? Texte de 2011 :
http://bloodredsun.com/2011/06/22/doubles-financial-calculations/
- Implémentation d'un nombre à virgule flottante « maison ».
Texte de 2012 : http://www.codeproject.com/Articles/146057/Minimalist-Floating-Point-Type
- Comment arrondir, par Danny Kalev en 2007 :
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=357
- Convertir d'une représentation à virgule flottante à
une représentation décimale à l'aide de gros entiers,
texte de Rick Regan en 2011 : http://www.exploringbinary.com/correct-decimal-to-floating-point-using-big-integers/
(pour une version plus rapide : http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/)
- Remplacer des nombres à virgule flottante par des entiers
en les changeant d'échelle, par Danny Kalev en
2007 : http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=355
- Comparatif de vitesse pour divers algorithmes de calcul de racines carrées,
par Mahmoud Hesham El-Magdoub en 2010 : http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
- Proposition d'optimisation numérique pour calculs de racines carrées,
par Liyuan Gao en 2012 : http://www.phailed.me/2012/08/somewhat-fast-square-root/
- À propos de la constante utilisée dans l'algorithme très
connu de calcul de l'inverse de la racine carrée, texte de Christian
Plesner Hansen en 2012 : http://blog.quenta.org/2012/09/0x5f3759df.html
- Textes généraux de John D. Cook :
- Bruce Dawson, programmeur dans le monde du jeu vidéo, offre une
série
d'articles très intéressants sur la manipulation de nombres
à virgule flottante, ce que c'est, ce que ce n'est pas, les périls,
les applications correctes, etc. :
- quelques trucs que l'on peut réaliser en manipulant des nombres
à virgule flottante et qui peuvent nous aider à comprendre
leur structure. Texte de 2012 : http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
- d'autres trucs, pas nécessairement heureux par contre. Texte
de 2012 : http://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/
- certaines valeurs ne devraient pas être déposées
dans un nombre à virgule flottante de simple précision (dans
un float), comme par exemple le temps écoulé
dans un programme. Ttexte de 2012 : http://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
- des valeurs qui semblent égales mais ne le sont pas, ou comment
se mettre les pieds dans les plats en comparant des nombres à virgule
flottante de manière impropre. Texte de 2012 :
http://randomascii.wordpress.com/2012/02/11/they-sure-look-equal/
- un complément d'information sur le texte portant sur la comparaison
impropre de nombres à virgule flottante. Texte de
2012 : http://randomascii.wordpress.com/2012/06/26/doubles-are-not-floats-so-dont-compare-them/
- une suite au texte sur la comparaison impropre de nombres à virgule
flottante. Texte de 2012 : http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
- comprendre la précision (en nombre de décimales) d'un
nombre à virgule flottante de simple précision. Non, ce
n'est pas simple. Texte de 2012 : http://randomascii.wordpress.com/2012/03/08/float-precisionfrom-zero-to-100-digits-2/
- expérimentation portant sur les nombres à virgule flottante,
à l'aide multiprogrammation
avec C++ 11.
Texte de 2012 : http://randomascii.wordpress.com/2012/03/11/c-11-stdasync-for-fast-float-format-finding/
- quelques surprises à propos du code manipulant des nombres à
virgule flottante, en particulier pour ce qui a trait au type des valeurs
intermédiaires des calculs. Texte de 2012 :
http://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/
- série de factoïdes sur les nombres à virgule flottante
de double précision, texte de 2012 :
http://randomascii.wordpress.com/2012/04/05/floating-point-complexities/
- à propos des exceptions (prudence par contre pour ce qui est
du sens de ce mot ici) dans la gestion des calculs des nombres à
virgule flottante. Texte de 2012 : http://randomascii.wordpress.com/2012/04/21/exceptional-floating-point/
- quelques valeurs particulières pour lesquelles la performance
des calculs sur des nombres à virgule flottante se dégrade.
Texte de 2012 : http://randomascii.wordpress.com/2012/05/20/thats-not-normalthe-performance-of-odd-floats/
- afficher un nombre à virgule flottante correctement et
efficacement n'est pas aussi simple qu'on pourrait le penser, et les
implémentations livrées avec les divers compilateurs donnent des résultats
légèrement différents les unes des autres. Texte de 2013 :
http://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/
- calculs sur des nombres à virgule flottante et résultats
déterministes, une analyse de 2013 :
http://randomascii.wordpress.com/2013/07/16/floating-point-determinism/
- vous souhaitez valider un algorithme sur des nombres à virgule
flottante? Simple : testez-les tous... Après tout, comme le rappelle Bruce
Dawson en 2014, il n'y en a que quatre
milliards!
http://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/
- parfois, il ne faut pas croire la documentation, et vérifier par
soi-même. En 2014, Bruce Dawson constate une
erreur dans une implémentation de fsin sur
ordinateurs Intel :
http://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/
- il arrive pourtant que les nombres à virgule flottante soient tout à
fait à propos, comme l'explique ce texte de 2017 :
https://randomascii.wordpress.com/2017/06/19/sometimes-floating-point-math-is-perfect/
- Série de textes d'Andrew
Koenig sur les impacts de décisions quant aux types de données lors de
calculs sur des nombres à virgule flottante :
- Texte de Guy
Steele et Jon White, en 1990, expliquant comment
afficher un nombre à virgule flottante de manière précise :
http://www.cs.washington.edu/education/courses/cse590p/590k_02au/print-fp.pdf
- Afficher un nombre à virgule flottante, texte de
Russ Cox en
2011 : http://research.swtch.com/ftoa
- Pourquoi la valeur 0.1 n'existe-t-elle pas de
façon exacte dans les représentations à virgule flottante
contemporaines? Texte de Rick Regan en 2012 :
http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
- Le coût des erreurs d'approximation, et une particularité « amusante »
résultant du fait que les additions sur des nombres à virgule flottante ne
sont pas associatives (donc qu'en général, si sont des nombres à virgule flottante) dû à ces erreurs. Texte de
Liyuan Gao en
2013 :
http://www.phailed.me/2013/01/floating-point-quirks/
- Afficher un nombre à virgule flottante entraîne parfois des résultats
quelque peu étonnants. À cet effet, un texte de
Raymond Chen en 2013 :
http://blogs.msdn.com/b/oldnewthing/archive/2013/02/28/10397976.aspx
- À propos de la difficulté d'écrire un analyseur statique capable de bien
prédire le comportement des programmes utilisant des nombres à virgule
flottante, texte de 2013 :
http://blog.frama-c.com/index.php?post/2013/07/06/On-the-precise-analysis-of-C-programs-for-FLT_EVAL_METHOD-2
- En 2013, Rick Regan nous explique que les
nombres à virgule flottante, c'est quelque chose d'un peu fou, quand on y
pense :
http://www.exploringbinary.com/floating-point-is-so-insane-even-a-ten-year-old-can-see-it/
- Texte de 2013 discutant des nombres à virgule
flottante et des calculs à précision « infinie », par Matt Adereth :
http://adereth.github.io/blog/2013/10/10/add-it-up/
- En 2013, Chris Vest rappelle que l'addition de
nombres à virgule flottante n'est pas associative :
http://chrisvest.name/floating-point-addition-is-not-associative.html
- En 2011, John D. Cook indique que les erreurs
résultat de calculs sur des nombres à virgule flottante le préoccupent bien
moins que les erreurs de modélisation ou celles d'approximation :
http://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/
- La résolution de constantes à la compilation peut introduire des
comportements suprenants à l'exécution lorsqu'elle est appliquée à des nombres
à virgule flottante, comme l'explique ce texte de 2013 :
http://kvanberendonck.wordpress.com/2013/12/06/be-aware-of-floating-point-optimizations-introduced-by-constant-folding-in-conformant-code/
- Quelques opérations telles que floor(),
ceil() ou round() telles qu'elles étaient
implémentées avant l'avènement des opérations
SSE 4.1, par Stéphanie
Rancourt en 2013 :
http://dss.stephanierct.com/DevBlog/?p=8
- À propos de la difficulté de réaliser une somme de nombres à virgule
flottante tout en réduisant au minimum l'erreur dans le calcul, par Richard
Lipton en 2014 :
http://rjlipton.wordpress.com/2014/10/05/how-to-add-numbers/
- À propos des propriétés que les nombres à virgule flottante... n'ont pas!
Un texte de Rico Mariani en 2014 :
http://blogs.msdn.com/b/ricom/archive/2014/10/15/non-properties-of-floating-point-numbers.aspx
- Une fable de 2014 sur la précision des nombres
à virgule flottante, avec des carottes et une fée :
http://blog.ruslans.com/2014/12/a-story-about-angry-carrot-and-floating.html
- Projeter efficacement une valeur dans un intervalle, selon Brian Rackle en
2014 :
http://blog.brainstembreakfast.com/update/c++/2014/08/18/range-mapping/
- Il arrive qu'un « bogue de compilateur » soit en fait un « bogue du
matériel », comme le relate Jack Whitham en 2015 en
discutant d'une erreur de calcul sur des nombres en virgule flottante :
http://blog.jwhitham.org/2015/04/gcc-bug-323-journey-to-heart-of.html
- Divers factoïdes à propos de la programmation à l'aide de nombres à
virgule flottante, par Edaqa Mortoray en 2015 :
http://mortoray.com/2015/07/06/essential-facts-about-floating-point-calculations/
- En
C++,
devrait-on préférer float,
double ou long double quand nous en avons
le choix? Texte de
Jason Turner en 2012 :
http://blog2.emptycrate.com/content/double-vs-float-which-better
- Choisir entre float ou
double, la vision d'Andrey Karpov (je pense; le texte n'est pas
signé) en 2017 :
https://hownot2code.com/2017/06/09/float-or-double/
- En 2017, Dennis Forbes explique ce qu'une programmeuse ou un programmeur
devrait savoir sur les nombres à virgule flottante :
https://dennisforbes.ca/index.php/2017/04/11/floating-point-numbers-an-infinite-number-of-mathematicians-enter-a-bar/
- Texte de 2017 qui se propose de démystifier la
question de la précision des nombres à virgule flottante :
https://blog.demofox.org/2017/11/21/floating-point-precision/
Arrondir un nombre à virgule flottante est un exercice
beaucoup plus ardu qu'il n'y
paraît à première vue :
À propos des nombres à virgule flottante
décimaux :
Dans un texte de 2012 (http://www.drdobbs.com/cpp/are-you-sure-that-your-program-works/240006889
si vous y avez accès), Andrew
Koening souligne la difficulté d'écrire des programmes qui
sont véritablement corrects, au sens où l'on peut s'en convaincre.
Il tient pour exemple une fonction telle que :
double f(double x, double y, double z) {
return x + y + z;
}
...qui semble tout à fait correcte, mais met en relief qu'un appel de
la forme suivante :
// ...
double res = f(1E100,1.0,-1E100);
// ...
...devrait en théorie déposer 1.0
dans res (puisque les valeurs
1E100 et -1E100 s'annulent lorsqu'on les
additionne, toujours en théorie) mais qu'il est aussi possible qu'on
obtienne 0.0 du fait que l'addition de
1.0 à 1E100 résultera peut-être
en 1E100 puisque 1.0 est
tout petit et 1E100 est énorme, à
un point tel qu'y ajouter 1.0 pourrait ne rien y
changer de par la nature même de l'encodage de ces approximations que
sont les nombres à virgule flottante. En pratique, il est donc
difficile de raisonner sur le caractère correct ou non de cette fonction
(en fait, c'est un cas où n'est pas
nécessairement égal à ,
donc où l'addition peut ne pas être commutative; on trouve des
cas semblables avec les entiers dans des cas de débordements).
Selon les langages de programmation :
- Nombres à virgule flottante avec
D :
- Nombres à virgule flottante avec Java :
- Nombres à virgule flottante avec
JavaScript :
- Nombres à virgule flottante avec
Kotlin :
- Nombres à virgule flottante sur la
plateforme
.NET :
Bien que les nombres à virgule flottante soient maintenant supportés
de manière native (matérielle) par la plupart des ordinateurs,
et bien que la majorité d'entre eux supportent la même représentation
IEEE, ce ne fut pas toujours le cas. Encore aujourd'hui, on a parfois recours
à des représentations « maison », typiquement
pour de l'arithmétique à point fixe :
À quel point les nombres à virgule flottante sont-ils étranges? Prenez
l'exemple suivant (en
C++, mais je l'ai adapté d'un exemple en Java et la
situation est indépendante du langage) :
#include <iostream>
using namespace std;
int main() {
int i = 2020202048;
i += 0.0f;
cout << i << endl;
}
... qui affichera :
... ce qui est pour le moins divertissant.