Flottants et précision
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectifs
Comprendre le mode de stockage des nombres flottants en informatique ;
Comprendre la notion de précision.
Mise en situation
En informatique on sait que toutes les données sont stockées en binaire. Pour les nombres décimaux, donc avec une virgule, on peut se demander comment stocker correctement la valeur sachant que la virgule n'est pas un nombre que l'on peut stocker : c'est un caractère. Une première approche pourrait être de simplement stocker la partie entière et la partie décimale séparément, mais ce n'est pas comme cela que ça fonctionne. C'est en réalité un peu plus complexe que cela, et en informatique on parle de nombres flottants, ou nombres à virgule flottante.
L'encodage des flottants
Les nombres flottants sont stockés sur 64 bits de façon à ce que le premier bit en partant de la gauche (on parle de bit de poids fort) détermine le signe : si ce bit vaut 0 le nombre est positif, si ce bit vaut 1 le nombre est négatif. Les onze bits suivants permettent d'encoder l'exposant et les cinquante deux bits restants permettent d'encoder la mantisse.
Les nombres sont dits flottants parce que la place de la virgule n'est pas fixe. Contrairement à ce que pourrait dicter l'intuition, il ne s'agit pas d'écrire les nombres avec un bit de signe, onze bits pour la partie entière et les cinquante deux bits restants pour la partie décimale.
Définition :
Les nombres flottants sont calculés ainsi, en binaire :
nbFlottant = signe * 2exposant * mantisse
La place de la virgule dans un nombre flottant dépend donc de son exposant.
Exemple : En décimal
Il est plus simple d'utiliser le système décimal pour comprendre. Le nombre -1.2345
sera représenté avec les données suivantes :
Signe :
négatif
Exposant :
-4
Mantisse :
12345
Le calcul donnera 10-4
, soit 0.0001
, multiplié par 12345
, soit 1.2345
, puis passé en négatif.
On constate que le changement de l'exposant, par -5
par exemple, donnera le nombre 0.12345
. La place de la virgule est donc flottante, et dépend de la valeur de l'exposant.
Exemple : Déclarer un flottant et l'utiliser
"""Pyhton."""
nb_float = 0.1
print(nb_float)
nb_float *= 0.1
print(nb_float)
nb_float += 1
print(nb_float)
/** JavaScript */
let nbFloat = 0.1
console.log(nbFloat)
nbFloat *= 0.1
console.log(nbFloat)
nbFloat += 1
console.log(nbFloat)
En Python comme en JavaScript on déclare et on manipule les nombres flottants comme les autres nombres.
Attention : Imprécisions
Tous les nombres ne sont pas parfaitement encodables avec cette méthode. Les nombres qui correspondent à une somme de puissance de deux sont écrits de façon exacte, les autres le sont de façon approchées, ce qui dans certains cas peut poser des problèmes de calcul.
Exemple : Problèmes d'approximation
En mathématiques, 0.1 + 0.2 = 0.3. La réponse à la question « est ce que 0.2 ajouté à 0.1 vaut 0.3 ? » est « oui ».
De même, 0.25 + 0.25 = 0.5, donc la réponse à la question « est ce que 0.25 ajouté à 0.25 vaut 0.5 ? » est « oui ».
Cependant, à cause des problèmes d'approximation des nombres flottants, ce n'est pas le cas en informatique.
"""Python."""
print(0.1 + 0.2 == 0.3)
print(0.25 + 0.25 == 0.5)
/** JavaScript */
console.log(0.1 + 0.2 === 0.3)
console.log(0.25 + 0.25 === 0.5)
Ces deux programmes affichent false
puis true
, parce que 0.1 ne peut pas être encodé correctement. Ainsi, quand les programmes additionnent 0.1 et 0.2, ils additionnent en réalité un nombre très proche de 0.1 et 0.2, donc le résultat obtenu n'est pas égal à 0.3 et le test est faux.
En revanche, 0.25 est encodé correctement donc la deuxième addition donne un résultat exact et le test est vrai.
Conseil : Eviter les problèmes d'approximation
Pour éviter les problèmes d'approximation lors de calculs ou de comparaisons avec des flottants il faut travailler avec mathjs, une bibliothèque conçue pour gérer les problèmes d'approximations des nombres flottants en JavaScript.
Complément : toPrecision()
Soit x = 0.3333
:
x.toPrecision(2)
renvoie0.33
.x.toPrecision(2)
est de type chaîne de caractère,x.toPrecision(2).substr(2)
renvoie33
.
À retenir
Les nombres flottants sont stockés sur 64 bits, ils sont dits flottants parce que la place de la virgule dépend de l'exposant.
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.