Question

Donc, Python a l'infini positif et négatif:

float("inf"), float("-inf")

Cela semble être le type de fonctionnalité qui doit être mis en garde. Y a-t-il quelque chose que je devrais être au courant?

Était-ce utile?

La solution

Vous pouvez toujours obtenir des valeurs non-numériques (NaN) à partir d'une simple arithmétique impliquant inf :

>>> 0 * float("inf")
nan

Notez que, normalement, ne recevez pas de valeur inf par le biais de calculs arithmétiques usuels:

>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')

La valeur inf est considérée comme une valeur très spéciale avec une sémantique inhabituelle. Il est donc préférable de connaître immédiatement un OverflowError via une exception, plutôt que d'avoir un code < > inf valeur injectée silencieusement dans vos calculs.

Autres conseils

L'implémentation de Python suit le norme IEEE-754 , qui peut être utilisée à titre indicatif, mais elle repose sur le système sous-jacent sur lequel elle a été compilée. < Une href = "http://www.python.org/dev/peps/pep-0754/" rel = "noreferrer"> différence de plate-forme peut se produire. Récemment, un correctif a été appliqué qui permet & infin; " infinity " ainsi que "inf" " , mais c'est d'une importance mineure ici.

Les sections suivantes s'appliquent également à tout langage qui implémente correctement l'arithmétique à virgule flottante IEEE; il n'est pas spécifique à Python.

Comparaison de l'inégalité

Lorsqu'il s'agit d'un opérateur infini et supérieur à > ou inférieur à < , les nombres suivants:

  • tout nombre incluant + inf est supérieur à -inf
  • tout nombre incluant -inf est inférieur à + inf
  • + inf est ni plus haut ni plus bas que + inf
  • -inf n'est ni supérieur ni inférieur à -inf
  • toute comparaison impliquant NaN est fausse ( inf n'est ni supérieur ni inférieur à NaN )

Comparaison de l'égalité

Lorsque l'égalité est comparée, + inf et + inf sont égaux, de même que -inf et -inf . C’est une question très discutée et qui peut sembler controversée, mais elle est conforme à la norme IEEE et Python se comporte exactement comme cela.

Bien sûr, + inf est différent de -inf et tout, y compris NaN lui-même, est différent de NaN .

Calculs à l'infini

La plupart des calculs avec l'infini produiront l'infini, à moins que les deux opérandes ne soient l'infini, que l'opération division ou modulo ou la multiplication à zéro ne comporte pas de règles spéciales:

  • multiplié par zéro pour lequel le résultat est indéfini, il donne NaN
  • lors de la division d'un nombre (sauf l'infini lui-même) par l'infini, ce qui donne 0.0 ou -0.0 & # 178;.
  • lors de la division (y compris modulo) de l'infini positif ou négatif par l'infini positif ou négatif, le résultat n'est pas défini, donc NaN .
  • lors de la soustraction, les résultats peuvent être surprenants, mais suivez sens commun des mathématiques :
    • en faisant inf - inf , le résultat est indéfini: NaN ;
    • en faisant inf - -inf , le résultat est inf ;
    • en faisant -inf - inf , le résultat est -inf ;
    • en faisant -inf - -inf , le résultat est indéfini: NaN .
  • lors de l'ajout, cela peut également être surprenant:
    • en faisant inf + inf , le résultat est inf ;
    • en faisant inf + -inf , le résultat est indéfini: NaN ;
    • en faisant -inf + inf , le résultat est indéfini: NaN ;
    • en faisant -inf + -inf , le résultat est -inf .
  • utiliser math.pow , pow ou ** est délicat, car il ne se comporte pas comme il se doit. Il lève une exception de dépassement de capacité lorsque le résultat avec deux nombres réels est trop élevé pour un flottant à double précision (il devrait renvoyer l'infini), mais lorsque l'entrée est inf ou -inf , il se comporte correctement et renvoie inf ou 0.0 . Lorsque le deuxième argument est NaN , il renvoie NaN , à moins que le premier argument ne soit 1.0 . Il existe plus de problèmes, pas tous abordés dans la documentation .
  • math.exp a les mêmes problèmes que math.pow . Une solution pour résoudre ce problème de débordement consiste à utiliser un code similaire à celui-ci:

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')
    

Notes

Remarque 1: comme avertissement supplémentaire, selon la définition du standard IEEE, si votre résultat de calcul est inférieur ou supérieur au résultat, le résultat ne sera pas une erreur de dépassement ou de dépassement, mais positif ou négatif. infini négatif: 1e308 * 10.0 donne inf .

Note 2: car tout calcul avec NaN renvoie NaN et toute comparaison avec NaN , y compris NaN est false , vous devez utiliser le math.isnan pour déterminer si un nombre est effectivement NaN .

Note 3: bien que Python prenne en charge l'écriture de float ('- NaN') , le signe est ignoré, car il n'existe pas de signe NaN en interne. Si vous divisez -inf / + inf , le résultat est NaN et non -NaN (rien n'existe de la sorte).

Remarque 4: veillez à vous fier à l'un des éléments ci-dessus, car Python s'appuie sur la bibliothèque C ou Java pour laquelle il a été compilé et tous les systèmes sous-jacents n'impliquent pas correctement ce comportement. Si vous voulez en être sûr, testez l'infini avant de faire vos calculs.

& # 185;) Récemment signifie depuis la version 3.2 . < br> & # 178;) Les points flottants prennent en charge les zéros positif et négatif. Par conséquent, x / float ('inf') conserve son signe et -1 / float ('inf') donne -0.0 , 1 / float (-inf) donne -0.0 , 1 / float ('inf') donne 0.0 et -1 / float (-inf) donne 0.0 . En outre, 0.0 == -0.0 est true , vous devez vérifier le signe manuellement si vous ne le souhaitez pas.

Il en va de même pour C99 .

La représentation en virgule flottante IEEE 754 utilisée par tous les processeurs modernes comporte plusieurs modèles de bits spéciaux réservés aux infinis positifs (signe = 0, exp = ~ 0, frac = 0), infinis négatifs (signe = 1, exp = ~ 0, frac = 0), et beaucoup de NaN (pas un nombre: exp = ~ 0, frac & # 8800; 0).

Tout ce dont vous devez vous soucier: certaines arithmétiques peuvent provoquer des exceptions / pièges en virgule flottante, mais ceux-ci ne se limitent pas à ceux-ci "intéressant". constantes.

J'ai trouvé une mise en garde que personne n'a encore mentionnée. Je ne sais pas si cela se produira souvent dans des situations pratiques, mais le voici par souci d'exhaustivité.

Généralement, le calcul d’un nombre modulo infinity se retourne sous forme de float, mais une fraction modulo infinity renvoie nan (et non un nombre). Voici un exemple:

>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan

J'ai signalé un problème sur le traqueur de bogues Python. Vous pouvez le voir à l'adresse https://bugs.python.org/issue32968 .

Mise à jour: cette sera corrigée dans Python 3.8 .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top