Comment gérer la comparaison de nombres à virgule flottante en Python

PythonPythonBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Les nombres à virgule flottante sont largement utilisés en Python pour les calculs numériques, mais leur représentation peut parfois entraîner un comportement inattendu lors de la comparaison de valeurs. Ce tutoriel vous guidera à travers les bases de la représentation des nombres à virgule flottante en Python et vous fournira des techniques pratiques pour effectuer des comparaisons précises de nombres à virgule flottante.

Représentation des nombres à virgule flottante en Python

En Python, les nombres à virgule flottante sont représentés selon la norme IEEE 754, qui est une norme largement adoptée pour représenter les nombres réels dans les ordinateurs. Cette norme définit le format et le comportement de l'arithmétique des nombres à virgule flottante, y compris la représentation de valeurs spéciales telles que l'infini positif et négatif, et le non-nombre (NaN).

Représentation des nombres à virgule flottante

Les nombres à virgule flottante en Python sont stockés dans un format de 64 bits, également connu sous le nom de nombre à virgule flottante « double précision ». Ce format se compose de trois composants :

  1. Bit de signe : Détermine si le nombre est positif ou négatif.
  2. Exposant : Représente la puissance de 2 à laquelle le mantisse est élevé.
  3. Mantisse : La partie fractionnaire du nombre.

La représentation d'un nombre à virgule flottante en Python peut être visualisée comme suit :

graph TD A[Sign Bit] --> B[Exponent] B --> C[Significand]

La norme IEEE 754 définit des motifs de bits spécifiques pour représenter des valeurs spéciales, telles que zéro positif et négatif, l'infini positif et négatif, et NaN.

Précision et arrondi

L'arithmétique des nombres à virgule flottante dans les ordinateurs n'est pas toujours exacte en raison du nombre fini de bits utilisés pour représenter les nombres. Cela peut entraîner des erreurs d'arrondi et un comportement inattendu lors de la comparaison de valeurs à virgule flottante. Par exemple, le code suivant illustre le problème :

import sys

x = 0.1
y = 0.2
print(x + y)  ## Output: 0.30000000000000004

La raison de ce comportement est que la représentation binaire de 0,1 et 0,2 ne peut pas être représentée exactement dans le nombre fini de bits utilisés pour stocker les nombres à virgule flottante.

Pour résoudre ce problème, diverses techniques de comparaison précise des nombres à virgule flottante sont discutées dans la section suivante.

Comparaison de nombres à virgule flottante

Comparer des nombres à virgule flottante en Python peut être difficile en raison des imprécisions inhérentes à leur représentation. Les techniques suivantes peuvent être utilisées pour effectuer des comparaisons précises de nombres à virgule flottante :

Comparaison par différence absolue

L'approche la plus simple consiste à vérifier si la différence absolue entre deux nombres à virgule flottante est inférieure à une petite valeur seuil. Cette méthode est appropriée lorsque vous connaissez la précision attendue des valeurs comparées.

import sys

x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon  ## Plus petit nombre à virgule flottante positif x tel que 1.0 + x!= 1.0
if abs(x + y - 0.3) < epsilon:
    print("x + y is equal to 0.3")
else:
    print("x + y is not equal to 0.3")

Comparaison par différence relative

Dans les cas où l'ordre de grandeur des nombres comparés varie, la comparaison par différence relative peut être plus appropriée. Cette méthode vérifie si la différence absolue entre les nombres est petite par rapport à l'ordre de grandeur des nombres.

import sys

x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
    print("x is equal to y")
else:
    print("x is not equal to y")

Comparaison par ULP (Unit in the Last Place)

La méthode de comparaison par ULP vérifie si la différence entre deux nombres à virgule flottante est inférieure à un certain nombre d'unités dans le dernier bit (ULP). Cette approche est plus précise que les méthodes de comparaison par différence absolue ou relative.

import math

x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
    print("x is equal to y")
else:
    print("x is not equal to y")

En utilisant ces techniques, vous pouvez comparer efficacement des nombres à virgule flottante en Python et gérer les imprécisions inhérentes à leur représentation.

Techniques pour une comparaison précise de nombres à virgule flottante

Lorsque vous travaillez avec des nombres à virgule flottante en Python, il est important d'utiliser des techniques appropriées pour garantir des comparaisons précises. Voici quelques techniques que vous pouvez utiliser :

Comparaison par différence absolue

La comparaison par différence absolue vérifie si la différence absolue entre deux nombres à virgule flottante est inférieure à une petite valeur seuil. Cette méthode est appropriée lorsque vous connaissez la précision attendue des valeurs comparées.

import sys

x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon  ## Plus petit nombre à virgule flottante positif x tel que 1.0 + x!= 1.0
if abs(x + y - 0.3) < epsilon:
    print("x + y is equal to 0.3")
else:
    print("x + y is not equal to 0.3")

Comparaison par différence relative

La comparaison par différence relative vérifie si la différence absolue entre deux nombres à virgule flottante est petite par rapport à l'ordre de grandeur des nombres. Cette méthode est utile lorsque l'ordre de grandeur des nombres comparés varie.

import sys

x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
    print("x is equal to y")
else:
    print("x is not equal to y")

Comparaison par ULP (Unit in the Last Place)

La méthode de comparaison par ULP vérifie si la différence entre deux nombres à virgule flottante est inférieure à un certain nombre d'unités dans le dernier bit (ULP). Cette approche est plus précise que les méthodes de comparaison par différence absolue ou relative.

import math

x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
    print("x is equal to y")
else:
    print("x is not equal to y")

En utilisant ces techniques, vous pouvez gérer efficacement les comparaisons de nombres à virgule flottante en Python et garantir le niveau de précision souhaité dans vos calculs.

Résumé

Dans ce tutoriel Python, vous avez appris les défis liés à la représentation des nombres à virgule flottante et les stratégies efficaces pour effectuer des comparaisons précises de nombres à virgule flottante. En comprenant les principes fondamentaux et en appliquant les techniques présentées, vous pouvez écrire un code Python plus robuste et fiable qui gère avec précision les opérations et les comparaisons de nombres à virgule flottante.