Forum Programmation.python Comment obtenir exceptionnellement un float de valeur nan ?

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
2
27
juin
2022

Bonjour,

Je cherche un moyen simple et élégant d’obtenir un float ayant pour valeur 'nan'.

Je ne vous parle pas de la manière explicite d’obtenir un float de valeur 'nan'.

a = float("nan")
type( a ) # → <class 'float'>
print( a ) # → nan

Par exemple, la page https://www.educative.io/answers/how-to-assign-nan-to-a-variable-in-python renseigne de manière erronée que l’on pourrait obtenir un float de valeur nan avec par exemple :

a = 0. / 0. # → ZeroDivisionError :(
a = (-1) ** (1/2) # → nombre complexe 1j ± 1e17 :(
a = float(a) # → TypeError
import math
a = math.log( -100 ) # → ValueError
a = math.asin( 1.1 ) # → ValueError

Selon-moi, oui, il y a de l’idée mais celui qui a fait cette page ne s’est pas donné la peine d’essayer… :(

Peut-être y a-t-il au moins une fonction dans le module math qui dans certains cas retourne un float de valeur 'nan' ?

Merci d’avance.

  • # Pas sûr d'avoir compris le besoin…

    Posté par  (site web personnel) . Évalué à 4.

    … mais math.nan existe ?

    Debian Consultant @ DEBAMAX

    • [^] # Re: Pas sûr d'avoir compris le besoin…

      Posté par  . Évalué à 4. Dernière modification le 27 juin 2022 à 15:32.

      Je crois que ça n'est pas ça qu'il demande (mais c'est mal demandé). Quand on lit la question, obtenir élégamment nan ne peut se faire qu'en demandant explicitement un nan (et pas appeler une opération qui renvoie nan, ce qui ne serait ni élégant, ni stable, ni rapide). Je pense que l'OP veut savoir quelle opération peut bien retourner nan si ni sqrt(-2.), ni 3./0., ni log(-3.) ne renvoient nan.

      Ça pourrait très bien être une sorte d'archaïsme progressivement remplacé par des erreurs plus précises?

      • [^] # Re: Pas sûr d'avoir compris le besoin…

        Posté par  . Évalué à 4.

        J’ai réussi en python en faisant ça…

        Python 3.9.2 (default, Feb 28 2021, 17:03:44)
        [GCC 10.2.1 20210110] on linux
        Type "help", "copyright", "credits" or "license" for more information.
        >>> import math
        >>> a = math.inf - math.inf
        >>> print (a)
        nan
        >>>

        Pas sûr que ce soit ce que veux l’auteur de la demande.

        • [^] # Re: Pas sûr d'avoir compris le besoin…

          Posté par  (site web personnel) . Évalué à 3.

          En effet, je cherche plutôt une fonction ou un calcul qui en temps normal donne un nombre float "valide" mais qui dans certaines situation donne un float de valeur 'nan'.

          Je suis en train de rédiger un cours pour mes élèves, un peu comme "Le domptage du serpent …" mais mis à jour et avec un style particulier. Je partagerai lorsque ce sera présentable ;)

          Pour les différents types intégrés, je propose un bout de code en exemple.

          page 4 du brouillon Python 3.10

          float("nan"), je trouve pas ça très "élégant" dans la mesure ou c’est "trivial". Cela ne montre pas ce qui peut amener un float à être dans cet état, contrairement à mon exemple pour la valeur "inf".

          • [^] # Re: Pas sûr d'avoir compris le besoin…

            Posté par  (site web personnel) . Évalué à 3.

            Dans ce cas, lire « CPython implementation detail » en bas de la doc du module math ?

            Debian Consultant @ DEBAMAX

            • [^] # Re: Pas sûr d'avoir compris le besoin…

              Posté par  (site web personnel) . Évalué à 2.

              Merci, oui, en effet il y a énormément de choses à dire sur tout ça, les "effets de bords", les cas "exceptionnels", erreur, pas erreur, mécanisme d’exception, sortie du logiciel ou retour d’une valeur particulière, None, float NaN, False, etc. Il y a aussi une histoire à tout cela :/

              C’est peut-être le bon endroit pour un petit encadré à ce sujet :)

          • [^] # Re: Pas sûr d'avoir compris le besoin…

            Posté par  . Évalué à 3.

            Tu peux leurs dire qu’en fonction des langages, bibliothèques qui font les calculs, parfois ça balance des erreurs, parfois un nan comme dans le cas de numpy.
            Leur expliquer que c’est un choix du langage, en c++ apparement, le langage remonte plutôt nan d’après ce site.

            • [^] # Re: Pas sûr d'avoir compris le besoin…

              Posté par  . Évalué à 2.

              En Haskell :

              *Main> sqrt (-1)
              NaN
              *Main>

              En Racket, une autre approche :

              > (sqrt -1)
              0+1i
              >
              • [^] # Re: Pas sûr d'avoir compris le besoin…

                Posté par  (site web personnel) . Évalué à 2.

                En effet, merci.
                En Python,

                import math
                math.sqrt( -1 ) # → ValueError 
                # par contre
                (-1)**(1/2) # → (6.123233995736766e-17+1j)

                Mise à part une légère imprécision, nous y sommes presque :)

                Je dois encore me renseigné à propos de numpy, dans quelles mesures est-il pertinent de remplacer l’usage de math par numpy ?
                Car en effet,

                import numpy
                numpy.sqrt(-1) # → float nan
    • [^] # Re: Pas sûr d'avoir compris le besoin…

      Posté par  . Évalué à 2.

      Effectivement :

      import math
      
      a = math.nan
      
      print (a)

      J’aurais pas parié ;-) mais c’est logique.

  • # numpy

    Posté par  (site web personnel) . Évalué à 4.

    Avec les fonctions log et arcsin de numpy j'obtiens bien des nan pour les deux derniers exemples (assaisonnés d'un message d'erreur).

    « IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace

  • # NaN

    Posté par  (site web personnel) . Évalué à 4.

    Les opérations menant normalement à NaN sont listées ici :
    https://en.wikipedia.org/wiki/NaN#Operations_generating_NaN

    Mais il semble que Python affiche d'autres erreurs (division par zéro par exemple pour 0./0.), sauf pour certaines opérations avec l'infini. Ce n'est donc pas un bon langage pour explorer le concept de NaN. Mieux vaut utiliser C ou Fortran.

  • # peut etre...

    Posté par  . Évalué à 4.

    throw nan? J ai toujours entendu dire que c'etait un barbare exceptionnel.

    Ou est la porte, deja…

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.