La norme IEEE754 définit la représentation en mémoire et les règles de calcul pour les nombres flottants.
IEEE754 est utilisée par la plupart des langages informatiques.
Cette norme induit des effets de bord qui provoquent des résultats erronés lors de certaines opérations mathématiques.
2. Human talker
Shaker technologies Javascript-IEEE754 version 1.0
Mickaël Ruau :
● formateur pour le titre développeur logiciel (niveau III)
à l’AFPA d’Angers
● consultant en gestion du cycle de vie du logiciel
(forges logicielles)
3. Objectif
Shaker technologies Javascript-IEEE754 version 1.0
A la fin de cette présentation, vous maîtriserez la
manipulation des nombres à virgule flottante.
- Vous comprendrez les effets de bords liés aux arrondis de
la norme IEEE754
- Vous serez capables d'améliorer l'exactitude des calculs
sur les nombres à virgule flottante.
4. Disclaimer
Shaker technologies Javascript-IEEE754 version 1.0
Le but est de sensibiliser
aux problèmes liés aux
calculs informatiques,
notamment en matière
financière (comptabilité,
paie, ecommerce...).
Je ne suis pas
mathématicien.
Je n’ai pas écrit la norme
IEEE754, je ne la
connais pas par coeur!
5. Références
Shaker technologies Javascript-IEEE754 version 1.0
http://blog.oaxoa.com/2008/03/22/weird-math-aka-ieee-754double-precision-floating-point-number-sukcs/
http://grouper.ieee.org/groups/754/faq.html
http://www.haypocalc.com/wiki/Standards_IEEE_754_et_854
http://floating-point-gui.de/languages/javascript/
http://www.ecmascript.org/
Standard ECMA-262 3rd Edition - December 1999
ECMA-262 5.1 Edition - June 2011
12. La cancellation
Shaker technologies Javascript-IEEE754 version 1.0
http://fr.wikipedia.org/wiki/Virgule_flottante#Pr.C3.A9cautions_d.27emploi
Les calculs en virgule flottante (...) présentent divers
désagréments, notamment leur précision limitée, qui se
traduit par des arrondis. (...)
Pour cette raison, les travaux de comptabilité ne sont pas
effectués en virgule flottante, car tout doit tomber juste au
centième près. En particulier, la soustraction de deux
nombres très proches provoque une grande perte de
précision relative : on parle de « cancellation ».
13. Pourquoi 0.1 n’est pas 0.1?
Shaker technologies Javascript-IEEE754 version 1.0
http://www.haypocalc.com/wiki/Standards_IEEE_754_et_854
En gros, on stocke les nombres sous la forme :
(signe, mantisse, exposant)
ce qui donne x = signe * mantisse * (2 ^ exposant).
Le signe vaut +1 ou -1, la mantisse est un nombre réel
tel que 1.0 <= mantisse < 2.0,
et l'exposant est une valeur entière.
Bien sûr, l'ensemble est codé en binaire !
14. Exemples de format de stockage
Shaker technologies Javascript-IEEE754 version 1.0
■ Le nombre 2 est stocké (+1, 1, 1),
c'est-à-dire : 2 = (+1) * 1 * (2 ^ 1).
■ Le nombre 3 est stocké (+1, 1.5, 1) :
3 = (+1) * 1.5 * (2 ^ 1).
■ Le nombre 10 est stocké (+1, 1.25, 3) :
10 = (+1) * 1.25 * 2^3.
16. Le signe
Shaker technologies Javascript-IEEE754 version 1.0
● (+1) si le nombre est positif
● (-1) si le nombre est négatif
17. La mantisse
Shaker technologies Javascript-IEEE754 version 1.0
● Si le nombre est supérieur à 1.5, il faut le diviser
successivement par deux, jusqu'à ce que sa valeur soit
inférieure ou égale à 1.5 (l'exposant sera le nombre de
division)
● Si le nombre est inférieur à 1, il faut le multiplier
successivement par deux, jusqu'à ce que sa valeur soit
supérieure ou égale à 1 (l'exposant sera le nombre
opposé de divisions).
18. Exemple : x = -10
Shaker technologies Javascript-IEEE754 version 1.0
● Le signe est égal à -1, car le nombre est négatif.
● On prend la valeur absolue : x=10.
Comme sa valeur est supérieur à 1, on divise par 2 :
x=5, exposant=1.
On continue : x=2.5 et exposant=2,
x=1.25 et exposant=3 : STOP !
Donc finalement, x=(-1) * 1.25 * (2^3).
19. Quelqu’un peut le faire pour moi?
Shaker technologies Javascript-IEEE754 version 1.0
http://babbage.cs.qc.cuny.edu/IEEE-754/
This page lets you examine the relationships among binary
and decimal numbers and three number formats described
by the IEEE-754-2008 floating-point standard.
You can enter a numeric value in any one of five formats,
and see all five corresponding values :
Decimal, Normalized Binary, Binary32 (single precision),
Binary64 (double precision),
and Binary128 (quad precision),
along with analyses of the binary structure of the floatingpoint formats.
24. " Il faut une infinie patience pour attendre toujours ce
qui n'arrive jamais. " (PIERRE DAC)
Shaker technologies Javascript-IEEE754 version 1.0
console.log
(99999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999);
//affiche 1e+308
console.log
(99999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999);
//affiche Infinity
25. " Il faut toujours prendre le maximum de risques avec
le maximum de précautions. " Rudyard Kipling
Shaker technologies Javascript-IEEE754 version 1.0
console.log(3+999999999999999);//affiche 1000000000000002
console.log(2+999999999999999);//affiche 1000000000000001
console.log(3+9999999999999999);//affiche 1000000000000004
console.log(2+9999999999999999);//affiche 1000000000000002
console.log(3+99999999999999999);//affiche 100000000000000000
console.log(2+99999999999999999);//affiche 100000000000000000
27. IEEE 754 overflow
Shaker technologies Javascript-IEEE754 version 1.0
http://fr.wikipedia.org/wiki/Virgule_flottante
Les calculs en virgule flottante sont pratiques, mais
présentent divers désagréments, notamment :
● une plage d'exposants limitée, pouvant donner lieux à
○ des « overflows » (lorsque le résultat d'une opération
est plus grand que la plus grande valeur
représentable)
○ et à des « underflows » (lorsqu'un résultat est plus
petit, en valeur absolue, que le plus petit flottant
normalisé positif),
○ puis à des résultats n'ayant plus aucun sens.
29. Number() = IEEE 64 bit
Shaker technologies Javascript-IEEE754 version 1.0
JavaScript is dynamically typed and will often convert
implicitly between strings and floating-point numbers (which
are IEEE 64 bit values). To force a variable to floatingpoint, use the global parseFloat() function.
var num = parseFloat("3.5");
30. https://github.com/dtrebbien/BigDecimal.js
Shaker technologies Javascript-IEEE754 version 1.0
Decimal Types
The best decimal type for JavaScript seems to be a port of Java’s BigDecimal
class, which also supports rounding modes:
var a = new BigDecimal("0.01");
var b = new BigDecimal("0.02");
var c = a.add(b); // 0.03
var d = c.setScale(1, BigDecimal.prototype.ROUND_HALF_UP);
31. https://github.com/dtrebbien/BigDecimal.js
Shaker technologies Javascript-IEEE754 version 1.0
How to Round
var num = 5.123456;
num.toPrecision(1) //returns 5 as string
num.toPrecision(2) //returns 5.1 as string
num.toPrecision(4) //returns 5.123 as string
Using a specific rounding mode:
new BigDecimal("1.25").setScale(1, BigDecimal.prototype.
ROUND_HALF_UP);