logo

Erreur de virgule flottante en Python

Python, un langage de programmation largement utilisé, excelle dans les tâches de calcul numérique, mais il n'est pas à l'abri des défis posés par l'arithmétique à virgule flottante. Les nombres à virgule flottante en Python sont des approximations de nombres réels, ce qui conduit à erreurs d'arrondi, perte de précision et annulations cela peut perturber les calculs. Nous pouvons repérez ces erreurs en recherchant des résultats étranges et utiliser des outilsnumpy.finfo>à surveiller la précision . Avec un peu de prudence et des astuces astucieuses, nous pouvons gardez ces erreurs sous contrôle et assurez-vous que nos calculs Python sont fiables. Dans cet article, nous explorerons les subtilités des erreurs à virgule flottante dans Python .

Que sont les nombres à virgule flottante ?

Les nombres à virgule flottante sont un moyen efficace de représenter des nombres réels dans les ordinateurs. Ils se composent de trois parties :



  • Significatif: Les chiffres réels représentant le numéro (par exemple, 3,14159)
  • Exposant: Indique de combien d'endroits il faut décaler la signification vers la gauche ou la droite (par exemple, -2 dans 3,14159 x 10^-2)
  • Base: Généralement 2 pour les ordinateurs, déterminant la façon dont les nombres sont représentés en interne

Pourquoi des erreurs en virgule flottante se produisent-elles ?

Les erreurs en virgule flottante surviennent parce que les ordinateurs stockent des nombres réels en utilisant un nombre fini de bits, ce qui conduit à des approximations et à des inexactitudes potentielles. Les nombres à virgule flottante ont des limites intrinsèques :

  • Précision finie : Seul un nombre limité de chiffres peut être stocké dans la mantisse, ce qui conduit à erreurs d'arrondi lors de la représentation de décimales exactes.
  • Perte de précision : Les opérations telles que l’addition ou la soustraction peuvent réduire davantage la précision, aggravant ainsi les effets de l’arrondi.
  • Sous-plein/Débordement : Des nombres extrêmement petits ou grands peuvent se situer en dehors de la plage représentable, ce qui conduit à sous-verse (devient zéro) ou débordement (devient l'infini).

Types d'erreurs à virgule flottante

a) Erreurs d'arrondi : Le plus courant, se produisant lorsqu'une décimale exacte doit être approchée pour s'adapter à la précision limitée d'un flottant.

b) Perte de précision : Les opérations ultérieures peuvent progressivement accumuler des erreurs d’arrondi, entraînant des inexactitudes importantes dans le résultat final.



c) Annulation catastrophique : Lors de la soustraction de nombres presque égaux de signes opposés, leurs chiffres significatifs s'annulent, laissant un résultat petit et inexact.

d) Trop-plein/Sous-plein : Cela se produit lorsque les calculs dépassent la plage représentable des valeurs flottantes, conduisant à des résultats inexacts ou dénués de sens.

Détection des erreurs à virgule flottante

  1. Observer des résultats inattendus : Comparer les valeurs calculées aux résultats attendus ou visualiser les données peut révéler des incohérences souvent causées par des erreurs.
  2. Utiliser des bibliothèques comme numpy.finfo> : Les bibliothèques aimentnumpy>fournir des outils commefinfo>pour vérifier la précision et les limites des différents types de données flottantes.

Erreur de virgule flottante Python

Nous discuterons ici de différents types d'exemples illustrant les erreurs à virgule flottante en Python :



Perte de précision dans la conversion décimale en binaire

Dans cet exemple, le nombre décimal 0,1 est converti en binaire. En raison du développement binaire infini de 0,1, seul un nombre fini de bits est utilisé, entraînant une perte de précision.

Python3




decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number} Binary: {binary_representation}'>)>

>

comment afficher une application dans Android
>

Sortir:

Decimal: 0.1 Binary: 0.100000000000000005551115123126>

Erreurs d'arrondi

Ici, le résultat de l'ajout de 1/3 trois fois devrait être de 1,0. Cependant, en raison d’erreurs d’arrondi dans la représentation de 1/3, la somme peut ne pas être exactement de 1,0.

Python3




result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0 Actual Result: {sum_result}'>)>

>

>

Sortir:

Expected Result: 1.0 Actual Result: 1.0>

Erreurs cumulatives dans les calculs itératifs

Cet exemple montre comment des erreurs cumulatives peuvent se produire dans les calculs itératifs. Ajouter 0,1 dix fois peut ne pas donner un résultat exact de 1,0 en raison des limitations de précision en virgule flottante.

Python3




total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0 Actual Result: {total}'>)>

>

>

Sortir:

Expected Result: 1.0 Actual Result: 0.9999999999999999>

Problèmes de comparaison

Dans ce cas, comparer la somme de 0,1 et 0,2 à 0,3 peut ne pas donner l'effet attendu.True>résultat en raison de l’imprécision inhérente aux nombres à virgule flottante.

Python3




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

>

Sortir:

a: 0.30000000000000004 b: 0.3 Equal: False>

Résultats inattendus dans les calculs

Ici, la soustraction de1e16>de la somme(1e16 + 1)>devrait donner 1, mais en raison d'erreurs en virgule flottante, le résultat peut ne pas être exactement 1.

Python3

file d'attente prioritaire java




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

>

Sortir:

Expected Result: 1 Actual Result: 0.0>

Comprendre la précision en virgule flottante

Ici, nous comprendrons la précision en virgule flottante : L'anomalie 1.2 – 1.0 en Python-

Défis de représentation

Comme on le sait, 1,2 – 1,0 = 0,2. Mais lorsque vous essayez de faire la même chose en Python, vous serez surpris par les résultats :

>>> 1.2 - 1.0>

Sortir:

0.199999999999999996>

Cela peut être considéré comme un bug de Python, mais ce n’est pas le cas. Cela n'a pas grand-chose à voir avec Python et bien plus avec la façon dont la plate-forme sous-jacente gère les nombres à virgule flottante. C'est un cas normal rencontré lors de la gestion interne de nombres à virgule flottante dans un système. C'est un problème causé par la représentation interne des nombres à virgule flottante, qui utilise un nombre fixe de chiffres binaires pour représenter un nombre décimal. Il est difficile de représenter certains nombres décimaux en binaire, ce qui entraîne dans de nombreux cas de petites erreurs d'arrondi. Nous connaissons des cas similaires en mathématiques décimales, de nombreux résultats ne peuvent pas être représentés avec un nombre fixe de chiffres décimaux, par exemple Exemple

10 / 3 = 3.33333333.......>

Dans ce cas, en prenant 1,2 comme exemple, la représentation de 0,2 en binaire est 0,00110011001100110011001100…… et ainsi de suite. Il est difficile de stocker en interne ce nombre décimal infini. Normalement, la valeur d'un objet float est stockée en virgule flottante binaire avec une précision fixe ( généralement 53 bits ). Nous représentons donc 1.2 en interne comme,

1.0011001100110011001100110011001100110011001100110011>

Ce qui est exactement égal à :

1.1999999999999999555910790149937383830547332763671875>

Gestion des erreurs de virgule flottante

Ici, nous allons discuter de différents exemples sur la façon de gérer les erreurs à virgule flottante en Python :

Arrondir à une décimale spécifique

En arrondissant le résultat à une décimale spécifique (par exemple, 2), vous pouvez atténuer l'impact des petites erreurs en virgule flottante.

Python3




result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result} Rounded Result: {rounded_result}'>)>

>

>

Sortir:

Original Result: 0.19999999999999996 Rounded Result: 0.2>

Utilisation de la classe décimale pour une haute précision

Ledecimal>module fournit leDecimal>classe, permettant une arithmétique de plus grande précision. Régler la précision avecgetcontext().prec>peut aider à gérer la précision de calculs spécifiques

Python3

comment retourner un tableau java




from> decimal>import> Decimal, getcontext> getcontext().prec>=> 4> # Set precision to 4 decimal places> result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> print>(f>'High Precision Result: {result}'>)>

>

>

Sortir:

High Precision Result: 0.2>

Utiliser des fractions pour des représentations exactes

Lefractions>Le module permet de travailler avec des représentations fractionnaires exactes, en évitant les erreurs en virgule flottante.

Python3




from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)>

>

>

Sortir:

Exact Fractional Result: 1/5>

Gestion des résultats intermédiaires avec décimal

Utilisez leDecimal>classe pour les calculs intermédiaires afin de minimiser les erreurs cumulées avant de reconvertir en float.

Python3




from> decimal>import> Decimal, getcontext> getcontext().prec>=> 6> # Set precision to 6 decimal places> intermediate_result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> final_result>=> float>(intermediate_result)># Convert back to float if needed> print>(f>'Intermediate Result: {intermediate_result} Final Result: {final_result}'>)>

>

>

Sortir:

Intermediate Result: 0.2 Final Result: 0.2>

Conclusion

Pourtant, tu te demandes pourquoi python ne résout pas ce problème , en fait, cela n'a rien à voir avec Python. Cela se produit parce que c'est la façon dont la plate-forme C sous-jacente gère les nombres à virgule flottante et, en fin de compte, avec l'inexactitude, nous aurons toujours écrit les nombres sous la forme d'une chaîne d'un nombre fixe de chiffres. Notez que cela est dans la nature même des binaires à virgule flottante : ce n'est pas non plus un bug dans Python ou C , et ce n'est pas non plus un bug dans votre code. Vous verrez le même type de comportement dans tous les langages prenant en charge l’arithmétique à virgule flottante de notre matériel, bien que certains langages puissent ne pas afficher la différence par défaut, ou dans tous les modes de sortie). Nous devons prendre en compte ce comportement lorsque nous nous soucions de problèmes mathématiques nécessitant des précisions exactes ou lorsque nous l'utilisons dans des instructions conditionnelles. Vérifier point flottant section dans la documentation Python pour plus de comportements de ce type.

Foire aux questions (FAQ)

1. Qu'est-ce qu'une erreur à virgule flottante en Python ?

Une erreur à virgule flottante en Python fait référence aux écarts entre les résultats attendus et réels lors de l'utilisation de nombres à virgule flottante, résultant des limitations de la représentation des nombres réels dans un système binaire.

2. Pourquoi 1.2 - 1.0> inégal 0.2> en Python ?

L'écart est dû aux difficultés inhérentes à la représentation des nombres décimaux en binaire. Des erreurs d'arrondi se produisent lors de la représentation binaire interne, conduisant à des résultats inattendus.

3. L'erreur de virgule flottante est-elle un bug en Python ?

Non, ce n'est pas un bug en Python. Il s’agit d’un problème courant en informatique lié à la façon dont les nombres à virgule flottante sont représentés en interne. Python adhère à la norme IEEE 754 pour l'arithmétique à virgule flottante.

4. Comment puis-je arrondir un résultat à virgule flottante à une décimale spécifique ?

Vous pouvez utiliser leround()>fonction pour arrondir un résultat à virgule flottante à une décimale spécifique. Par exemple,rounded_result = round(result, 2)>.

5. Quel est le decimal> module, et comment aide-t-il à gérer les erreurs en virgule flottante ?

Ledecimal>module fournit leDecimal>classe pour une arithmétique de plus grande précision. Réglage de la précision et utilisationDecimal>peut aider à atténuer les erreurs en virgule flottante.