Vous êtes sur une version archivée de lyceum.fr de l'année 2019/2020.  Revenir au présent.

Chapitre 5: Représentation approximative des nombres réels


Programme Officiel

Contenus

Capacités attendues

Commentaires

Représentation approximative des nombres réels: notion de nombre flottant

Représentation approximative des nombres réels: notion de nombre flottant

0.2 + 0.1 n’est pas égal à 0.3. Il faut éviter de tester l’égalité de deux flottants. Aucune connaissance précise de la norme IEEE-754 n’est exigible.

Lien vers le programme complet

Nous avons appris à encoder des nombres entiers naturels, et relatifs, et nous avons vu que les limites physiques des machines imposaient des limites sur l'étendue des valeurs. Par exemple, sur un octet on dispose de 2 8 = 256 2^8 = 256 valeurs distinctes qui permettent d'encoder:

  • des nombres entiers naturels entre 0 et 255.
  • des nombres entiers relatifs entre -128 et 127.

Maintenant que nous allons tenter de coder les réels, les limites de notre machine vont encore entraîner des limites sur l'étendue des valeurs, mais également sur la précision des valeurs.

Ainsi, si on effectue le calcul 0.2 + 0.1 0.2 +0.1 en Python, on obtient:

>>> 0.2 + 0.1
0.30000000000000004

Et contre toute attente, certains tests que l'on aurait cru positifs renvoient des valeurs négatives(ce que l'on appelle un faux négatif):

>>> 0.2 + 0.1 == 0.3
False

Notion de nombre flottant

En informatique plutôt que parler d'encodage des réels, on préfère parler de nombres flottants(floating point en anglais), car il existe une infinité de réels infiniment proches les uns des autres, or en informatique, nous serons forcément limités dans l'étendue et la proximité des nombres à virgule.

Ainsi un calcul avec des nombres à virgule ne peut-être qu'approximatif. Cependant plus on augmente la taille du registre du processeur et plus nous pourrons représenter de valeurs, et plus nos calculs gagneront en précision.

Tests d'égalité sur les flottants

Comme nous sommes limités sur la précision des flottants, on transforme les tests d'égalités en tests d'inégalités à une précision donnée.

Ainsi:

>>> 0.2 + 0.1 == 0.3
False

Par contre, en utilisant une précision du millionième:

>>> import math # pour utiliser la fonction valeur absolue  fabs()
>>> precision = 1E-6
>>> math.fabs((0.2 + 0.1) - 0.3)  < precision
True

D'ailleurs la bibliothèque math de Python inclut à cet effet la fonction math.isclose().

Principe du codage

On représente un nombre à virgule sous la forme:

s   m 2 n s\ m \cdot 2^n

IEEE754 Format General.png
« IEEE754 Format General » par GMjeanmattTravail personnel. Sous licence CC BY-SA 3.0 via Wikimedia Commons.

Supposons un nombre flottant codé sur un octet utilisant 1 bit de signe, 3 bits pour l'exposant et 4 bits pour la mantisse: 1 101 1011

  • s s est le signe représenté par le bit de poids fort:

    • s = 0 s=0 : signe + +
    • s = 1 s=1 : signe -

Notre codage représente donc un nombre négatif.

  • n n est l'exposant représenté par un entier relatif décalé et non en complément à deux, afin de faciliter la comparaison des exposants. Ce décalage est de 2 e 1 1 2^{e-1} - 1 (e représente le nombre de bits de l'exposant)

L'exposant a pour valeur 101 codé sur 3 bits, il doit être décalé de 2 2 1 = 3 2^{2} - 1 = 3 . Ainsi, puisque 10 1 2 = 5 10 101_2 = 5_{10} , l'exposant 101 correspond à un exposant de 5-3=2.

  • m m est la mantisse qui est un nombre binaire à virgule compris entre 1 inclus et 2 exclus. Le seul chiffre avant la virgule étant toujours 1, il n'est pas représenté(on le dit implicite), et le codage binaire de la mantisse représente donc uniquement les chiffres après la virgule qui sont en base 2 des demis, des quarts, des huitièmes...

Dans notre exemple, la mantisse est: 1011, elle représentera le nombre:

m = 1 + 1 2 + 0 2 2 + 1 2 3 + 1 2 4 = 1 , 6875 m = 1 + \frac{1}{2} + \frac{0}{2^2} + \frac{1}{2^3}+ \frac{1}{2^4} = 1,6875

Le code 1 101 1011 sur un octet utilisant 1 bit de signe, 3 bits pour l'exposant et 4 bits pour la mantisse représente donc:

1 , 6875 2 2 = 6 , 75 - 1,6875 \cdot 2^{2}= -6,75

La norme IEEE 754

L’IEEE 754 est une norme pour la représentation des nombres à virgule flottante en binaire. Elle est la norme la plus employée actuellement pour le calcul des nombres à virgule flottante dans le domaine informatique. Source Wikipedia

Cette norme définit notamment 2 formats pour représenter des nombres à virgule flottante:

  • simple précision (32 bits : 1 bit de signe, 8 bits d'exposant (-126 à 127), 23 bits de mantisse),

Représentation simple précision flottants IEEE 754
Par GMjeanmattTravail personnel, CC BY-SA 3.0, Lien

  • double précision (64 bits : 1 bit de signe, 11 bits d'exposant (-1022 à 1023), 52 bits de mantisse).

IEEE754 double precision.png
Par GMjeanmattTravail personnel, CC BY-SA 3.0, Lien

Réaliser la conversion en base 2 de la valeur approchée de pi: 3.14159265359
  • en simple précision: ici
  • en double précision: ici

Comparer la précision obtenue dans les deux cas.