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 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    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...

  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 721
    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 721
    Points : 31 044
    Points
    31 044
    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...

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