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

Fortran Discussion :

double precision & parameter


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2004
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 76
    Par défaut double precision & parameter
    Bonjour,
    Voici ce que je trouve dans mon code (fortran 77):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DOUBLE PRECISION INFINI, MINFINI, ZERO, EPS, ONE, COEF
    PARAMETER (INFINI=1.E+15,ZERO=0.E0,EPS=1.E-50,ONE=1E0,COEF=-0.5E0)
    qui donne un avertissement à la compilation :
    ifort -fPIC -fpp -warn all -nogen-interface -g -c ALLO.F -o ALLO.o
    ALLO.F(88): warning #7919: The value was too small when converting to REAL(KIND=4); the result is zero. [1.E-50]
    PARAMETER (INFINI=1.E+15,ZERO=0.E0,EPS=1.E-50,ONE=1E0,COEF=-0.5E0)
    ---------------------------------------------^
    Comme c'est très bien expliqué dans la faq, le compilateur semble ici considérer que EPS est un REAL (donc compris entre 1e-32 et 1e32).
    J'en déduis que ce qu'on met dans dans PARAMETER est par défaut un REAL malgré la déclaration de la ligne du dessus.
    Voyez-vous comment exiger qu'il soit considéré comme un double precision ?
    Pensez-vous que cette façon de faire du compilateur sera identique avec tous les compilateurs ? je demande ça car bizarrement je ne vois aucun message d'avertissement sous windows (compilateur intel).
    Par contre gfortran fait le même genre d'avertissement.
    gfortran -fPIC -x f77-cpp-input -Wall -O -funroll-all-loops -c ALLO.F -o ALLO.o
    ALLO.F:88.51:

    PARAMETER (INFINI=1.E+15,ZERO=0.E0,EPS=1.E-50,ONE=1E0,COEF=-0.5E0)
    1
    Warning: Real constant underflows its kind at (1)
    Merci !

  2. #2
    Membre éprouvé
    Homme Profil pro
    Ingénieur modélisation aérodynamique
    Inscrit en
    Juillet 2009
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur modélisation aérodynamique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2009
    Messages : 105
    Par défaut
    Bonjour,

    Il y a effectivement un petit illogisme de language lorsqu'on compile en fortran77 pour l'attribut "PARAMETER" :

    Tu dois activer le format REAL*8 par défaut au niveau du compilateur :
    pour ifort => option "-r8"
    pour gfortran => option "-fdefault-real-8"

    Attention,
    ---------
    cette option ne fait pas passer toutes les variables REAL de ton code en REAL*8. Celles que tu déclares en REAL*4 ne pourront toujours pas être affectés par une valeur en dehors de [1e-32 , 1e32] (avec les négatifs bien sur)
    Ce petit "bug" n'apparait que lorsque tu utilises l'attribut "PARAMETER" en fortran77. PARAMETER réclame un argument de type "REAL" et le format de ce "REAL" est le format par défaut du compilateur.

    Par contre le code suivant ne pose pas de soucis même en F77 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    program test_real_8
       implicit none
       real*8  :: eps
     
       eps = 1.0D-50
    end
    Et ton code marche parfaitement en compilant avec la version fortran90 (option "-free") de ifort car l'attribut PARAMETER a été corrigé.

    Tu a donc deux solutions :
    - soit tu passe ton code en f90
    - soit tu rajoutes l'option de compilation cité au dessus pour changer le format par défaut de tes REAL


    (juste pour préciser : DOUBLE PRECISION = REAL*8)

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Par défaut
    A mon avis le compilateur se trompe lorsqu'il interprète 1.E-50

    Essaie de remplacer 1.E-50 par 1.D-50 pour indiquer la constante est en double précision.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur modélisation aérodynamique
    Inscrit en
    Juillet 2009
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur modélisation aérodynamique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2009
    Messages : 105
    Par défaut
    Citation Envoyé par mipicard
    A mon avis le compilateur se trompe lorsqu'il interprète 1.E-50

    Essaie de remplacer 1.E-50 par 1.D-50 pour indiquer la constante est en double précision.
    Je ne pense pas, les notation D et E sont équivalentes pour les compilateurs

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Par défaut
    Le compilateur ne se trompe pas et il n'y a pas d'illogisme. Il est important de comprendre que l'expression à la droite du égal est évaluée indépendamment du côté gauche.

    Le problème est fort simple. 1e-50 est une constante (simple) real. Tu as beau affecter cette constante à un double, ça ne change pas la nature de la constante. Le problème est dans le fait que 1 x10^-50 n'est pas représentable en real. Tu dois donc forcer le type de la constante en double en utilisant un d plutôt qu'un e (1d-50).

    C'est exactement le même problème que le code suivant (en f90):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print *, 3.1415926535; end
    Ce code devrait imprimer 3.141592 ou 3.141593 parce que la constante littérale est en simple real. La précision additionnelle n'est pas représentable en real (4). Pour avoir toute la précision, il faut forcer la constante en double :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print *, 3.1415926535d0; end

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2004
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 76
    Par défaut
    Merci pour vos réponses et explications, je comprends mieux. et remplacer le e par le d enlève logiquement l'avertissement.

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

Discussions similaires

  1. Optimisation de code et double precision
    Par Bénarès77 dans le forum Fortran
    Réponses: 4
    Dernier message: 26/11/2009, 18h34
  2. [c] double precision
    Par nakor dans le forum C
    Réponses: 4
    Dernier message: 30/10/2009, 17h06
  3. Champ BCD & Champ DOUBLE PRECISION
    Par WebPac dans le forum Oracle
    Réponses: 10
    Dernier message: 21/03/2007, 17h21
  4. IBExpert : troncature des double precision ?
    Par Magnus dans le forum Outils
    Réponses: 1
    Dernier message: 25/08/2005, 15h07
  5. Passer de DOUBLE PRECISION en NUMERIC
    Par alex4 dans le forum SQL
    Réponses: 5
    Dernier message: 18/10/2004, 16h24

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