IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Pour le fun, petit calcul pouvant être faux (awk,perl5,python)


Sujet :

Shell et commandes GNU

  1. #1
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 284
    Points : 12 739
    Points
    12 739
    Par défaut Pour le fun, petit calcul pouvant être faux (awk,perl5,python)
    Bonjour,
    Suite à la lecture sur un tutoriel de perl6 sur ce site où il est fait mention de cette erreur, la voici montré ici via awk, mais que l'on rencontre dans presque tous les langages:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ awk 'BEGIN{print 0.3-0.2}'
    0.1
    $ awk 'BEGIN{print 0.3-0.1}'
    0.2
    $ awk 'BEGIN{print 0.3-0.2-0.0}'
    0.1
    $ awk 'BEGIN{print 0.3-0.2-0.1}'
    -2.77556e-17
    Bon, là, on voit que le dernier calcul est faux...
    Par contre, ce que je trouve gênant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk 'BEGIN{printf("%f\n",0.3-0.2-0.1)}'
    -0.000000
    Et c'est pareil en perl5 ou python (2 ou 3)...
    Python2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ python -c 'print "%f" % (0.3-0.2-0.1)'
    -0.000000
    $ python -c 'print 0.3-0.2-0.1'
    -2.77555756156e-17
    Python3:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ python3 -c 'print( "%f" % (0.3-0.2-0.1))'
    -0.000000
    $ python3 -c 'print((0.3-0.2-0.1))'
    -2.7755575615628914e-17
    Perl5:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ perl -e 'printf("%f\n",0.3-0.2-0.1)'
    -0.000000
    $ perl -e 'print 0.3-0.2-0.1."\n"'
    -2.77555756156289e-17
    Note d'Attention: les résultats bons sont liés au fait que l'on représente les nombres en tant que flottant et non en tant qu'exposant.
    Cordialement.

  2. #2
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Bon, là, on voit que le dernier calcul est faux...
    Si tous les calculs faux l'étaient aussi peu que celui là :
    L'erreur, rapportée aux valeurs utilisées, correspondrait à une imprécision de l'ordre de 40 nanomètres (0.04 millièmes de millimètre) pour la mesure de la distance de la terre à la lune, pas de quoi fouetter un chat.

    Par contre, ce que je trouve gênant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk 'BEGIN{printf("%f\n",0.3-0.2-0.1)}'
    -0.000000
    Pourquoi gênant, +0 et égal à -0, non ?
    ɹǝsn *sıɹɐlos*

  3. #3
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 284
    Points : 12 739
    Points
    12 739
    Par défaut
    On est d'accord, si derrière on ne doit pas par exemple divisé 2 par la valeur retournée...
    quoi que: dans un cas le nombre devient grand, dans l'autre on gère une exception.

    Sinon, ce qui m'a perturbé, c'est qu'en passant par des flottants, on n'a pas l'erreur, c'est ensuite que j'ai réalisé que l'erreur était exclusivement sur la représentation en exposant.

    Mais bon, comme dit dans le titre, c'est juste pour le fun
    Cordialement.

  4. #4
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Dans tous les cas présentés, awk, perl, python, etc.. travaillent avec des nombres flottants en double précision IEEE 754. Les différences ne sont pas dues au mode de représentation choisi, notation scientifique (ce que tu appelles exposant) ou décimale (ce que tu appelles flottant), mais à la précision demandée ou par défaut et les arrondis qui en découlent.
    Si tu veux toutes les décimales sans utiliser la notation scientifique, tu peux le préciser dans le format de printf:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk 'BEGIN{printf("%.56f\n",0.3-0.2-0.1)}'
    -0.00000000000000002775557561562891351059079170227050781250
    Pareil en notation scientifique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk 'BEGIN{printf("%.39e\n",0.3-0.2-0.1)}'
    -2.775557561562891351059079170227050781250e-17
    ɹǝsn *sıɹɐlos*

  5. #5
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 284
    Points : 12 739
    Points
    12 739
    Par défaut
    Ahhh, je comprends mieux mon erreur de compréhension, super.

    Merci Bien
    Cordialement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SQL] [Avis] - Xml ou SQL pour afficher 15 petites news ?
    Par ShinJava dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 23/03/2006, 14h25
  2. Cherche tuteur pour encadrer un petit projet.
    Par mikaloop dans le forum Access
    Réponses: 11
    Dernier message: 05/03/2006, 18h15
  3. [ImageMagick] Image ne pouvant être affichée car elle contient des erreurs
    Par hutchuck dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 09/12/2005, 13h59
  4. Choix du langage pour faire un petit utilitaire
    Par jejam dans le forum Langages de programmation
    Réponses: 9
    Dernier message: 07/12/2005, 17h29
  5. [debutant] pour debbuger un petit prog avec menu
    Par niluge01 dans le forum Windows
    Réponses: 3
    Dernier message: 22/11/2003, 14h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo