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

 C Discussion :

Conversion du Fortran en C : problème avec l'instruction goto !


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 12
    Points
    12
    Par défaut Conversion du Fortran en C : problème avec l'instruction goto !
    Bonjour à tous,

    Je souhaiterais convertir un petit programme Fortran en C.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    real*8 function gint (g1,g2,eps,pp,Re,s1,c1,ssig,csig,along1)
    implicit real*8 (a-h,o-z)
       n = 8
    1  h = (g2-g1) / dfloat(n)
       hh = 0.5D0*h
       g = h*0.5773502691896D0
       y = g1 + (h-g)*0.5D0
       gint2 = eld(y,pp,Re,s1,c1,ssig,csig,along1)+
               + eld(y+g,pp,Re,s1,c1,ssig,csig,along1)
       do m = 1,n-1
             gint2 = gint2 + eld(y+h-g,pp,Re,s1,c1,ssig,csig,along1)+
                       + eld(y+h,pp,Re,s1,c1,ssig,csig,along1)
             y = y + h
       enddo
       gint2 = gint2*hh
       if (n.eq.8.or.abs(gint1-gint2).gt.eps*abs(gint1)) then
           n = n*2
           gint1 = gint2
           if (n.lt.1024) goto 1
       endif
       gint = gint2+(gint2-gint1)/15.0D0
       return
       end
    Désolé pour le manque de clarté éventuelle, à ma décharge, ce n'est pas moi l'auteur de cette fonction Fortran.

    J'ai pensé à la boucle do_while sur la valeur de n (inférieure à 1024)

    Le problème est que ce goto est situé à l'intérieur d'une boucle IF.

    Je crois pas qu'il soit possible de fermer avec le while du do_while à l'intérieur du if(n eq8 etc...) converti en C, et si je mets ce while à l'extérieur, le souci est que ce IF peut faire tourner la boucle à l'infini, pour peu que la 2ème condition ne soit pas réalisée.

    Je patauge un peu, je ne demande pas à ce qu'on me serve le programme en C sur un plateau d'argent, mais si je pouvais avoir quelques pistes sur la structure à adopter pour m'affranchir de ce goto...

    Je vous remercie de vos lumières, en vous souhaitant un bon week-end.

  2. #2
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    real*8 function gint (g1,g2,eps,pp,Re,s1,c1,ssig,csig,along1)
    implicit real*8 (a-h,o-z)
       n = 8
    while ( 1 )  //Boucle toujours ( cette ligne serait ton label 1 )
    {
         h = (g2-g1) / dfloat(n)
       hh = 0.5D0*h
       g = h*0.5773502691896D0
       y = g1 + (h-g)*0.5D0
       gint2 = eld(y,pp,Re,s1,c1,ssig,csig,along1)+
               + eld(y+g,pp,Re,s1,c1,ssig,csig,along1)
       do m = 1,n-1
             gint2 = gint2 + eld(y+h-g,pp,Re,s1,c1,ssig,csig,along1)+
                       + eld(y+h,pp,Re,s1,c1,ssig,csig,along1)
             y = y + h
       enddo
       gint2 = gint2*hh
       if (n.eq.8.or.abs(gint1-gint2).gt.eps*abs(gint1)) then
           n = n*2
           gint1 = gint2
           if ( n >= 1024 )
             break;  //Sortie de la boucle
         endif
    }
       gint = gint2+(gint2-gint1)/15.0D0
       return
       end
    Le code en orange est le code fortran à tranposer en c(++)

    Explication :
    est une boucle avec un test toujours true ( ici 1 ), elle boucle sans fin, jusqu'a ce que tu fasse

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Salut,

    Le souci est que dans le cas où nous n'avons ni n=8 ni la deuxième condition, alors l' "intérieur" du if du C n'est pas parcouru, il n'y a pas doublement de n ni de break, et le while se répète joyeusement à l'infini... :/

    Tandis que dans le code Fortran, sauf erreur de ma part : si aucune des deux conditions du IF n'est vérifiée, alors il ne revient pas à la ligne 1, puisque l' "intérieur" du IF n'est pas parcouru. Il passe direct à la ligne "gint = gint2+(gint2-gint1)/15.0D0" et la fonction nommée gint est alors presque finie...

    Peut-être que je me trompe...

    Cela dit je te remercie du temps que tu as pris pour me répondre.

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    double gint (double g1, double g2, double eps, double pp,
                 double Re, double s1, double c1, double ssig, 
                 double csig, double along1)
    {
       int    n=8, m ;
       double h, hh, g, y, gint1=0.0, gint2=0.0 ;
     
       while  ( (n < 1024) && ((n == 8) || (fabs(gint1-gint2) > (eps*fabs(gint1)))) )
         {
             h = (g2-g1) / (double)(n) ;
             hh = 0.5 *h ;
             g = h*0.5773502691896 ;
             y = g1 + (h-g)*0.5 ;
     
             gint2 = eld (y,pp,Re,s1,c1,ssig,csig,along1)+
                       eld(y+g,pp,Re,s1,c1,ssig,csig,along1) ;
     
             for ( m = 1 ; m <= n-1 ; m++ )
               {
                  gint2 = gint2 + eld(y+h-g,pp,Re,s1,c1,ssig,csig,along1)+
                             eld(y+h,pp,Re,s1,c1,ssig,csig,along1) ;
                  y = y + h ;
                }
     
             gint2 = gint2*hh ;
     
             n = n*2 ;
             gint1 = gint2 ;
         }
     
       return ( (gint2+(gint2-gint1)/15.0) );
    }


    Explication :

    Le point central de ce qui te pose problème est :

    Code Fortran : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       n = 8
    1  ....
       if (n.eq.8.or.abs(gint1-gint2).gt.eps*abs(gint1)) then
           ...
           if (n.lt.1024) goto 1
       endif

    Si on lit correctement, on voit que :

    • lorsque n=8, c'est à dire au départ, on rentre dans le test, et que comme n*2 est < 1024, on va en 1.
    • ensuite, si "abs(gint1-gint2).gt.eps*abs(gint1)" et que n < 1024, on va en 1


    Ce qui se traduit donc par :

    tant que n < 1024 (et n = 8 rentre dans ce cas) ET QUE on a la condition de > (sauf si n = 8), alors on continue

    D'où un :


    Auquel il faut ajouter la condition du test (mais qui n'est à faire QUE QUAND n n'est pas égal à 8).

    D'où la deuxième condition du while :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( (n == 8) || (fabs(gint1-gint2) > (eps*fabs(gint1)))

    ici, quand n = 8 on n'évalue même pas le test, et on ne l'évalue que à partir de la première boucle..

    CQFD...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Marty MacFly Voir le message
    Le problème est que ce goto est situé à l'intérieur d'une boucle IF.
    boucle if pfff...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 10
    Dernier message: 02/03/2009, 17h24
  2. Fortran sous Vista : problèmes avec cygwin
    Par crow56 dans le forum Fortran
    Réponses: 3
    Dernier message: 18/07/2008, 13h33
  3. [aide]probléme avec l'instruction group by
    Par diden138 dans le forum Bases de données
    Réponses: 4
    Dernier message: 25/05/2007, 07h09
  4. Problème avec l'instruction IN : 16 bits retournés
    Par HadiNET dans le forum Assembleur
    Réponses: 4
    Dernier message: 11/02/2006, 17h43
  5. Problème avec une instruction OUTER /Postgres
    Par Volcomix dans le forum Langage SQL
    Réponses: 14
    Dernier message: 21/04/2004, 16h56

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