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 :

effectuer des calculs dans une constante symbolique


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut effectuer des calculs dans une constante symbolique
    Bonjour, j'ai peur de poser une question un peu bête, mais j'aimerais en avoir le coeur net : est-ce que si je fais un calcul dans un #define, sera-t-il sera effectué lors de la compilation ? Je m'explique, je désire faire la chose suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2 sqrt(2.)
    #define CST1 -3./SQRT2
    dans lors de la compilation, dès qu'il y a un SQRT2 ou un CST1, l'expression sera remplacée par sqrt(2.) et par -3./sqrt(2.). Mais dois-je plutôt écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2  1.414213562373095
    #define CST1 -2.121320343559642  /* -3/sqrt(2.) */
    pour être sûr que le code remplacé contiendra les valeurs numériques et non le calcul à refaire à chaque fois ? Je pense que les compilo doivent être suffisament développés pour faire cette optimisation tout seul (dois-je rajouter des options ?) mais j'aimerais en avoir le coeur net.

    Autre question, d'un point de vu lisibilité, que vaut-il mieux faire : faire un fichie defines.h qui contient tous mes #define et que j'inclus donc dans chaque fichier source ou bien n'écrie que les #define correspondants à chaque fichier source ?

    Merci.

  2. #2
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par salseropom
    Bonjour, j'ai peur de poser une question un peu bête, mais j'aimerais en avoir le coeur net : est-ce que si je fais un calcul dans un #define, sera-t-il sera effectué lors de la compilation ? Je m'explique, je désire faire la chose suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2 sqrt(2.)
    #define CST1 -3./SQRT2
    dans lors de la compilation, dès qu'il y a un SQRT2 ou un CST1, l'expression sera remplacée par sqrt(2.) et par -3./sqrt(2.). Mais dois-je plutôt écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2  1.414213562373095
    #define CST1 -2.121320343559642  /* -3/sqrt(2.) */
    pour être sûr que le code remplacé contiendra les valeurs numériques et non le calcul à refaire à chaque fois ? Je pense que les compilo doivent être suffisament développés pour faire cette optimisation tout seul (dois-je rajouter des options ?) mais j'aimerais en avoir le coeur net.
    Etant donné que vos defines font appel à une fonction (sqrt()), la valeur ne sera pas calculée à la compilation.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Salut donc si je fais un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define THIRD 1./3.
    là ma constante sera calculée lors de la compilation. Qu'est-ce qui gêne le compilo à apeler la fonction sqrt() lors de la compilation s'il est capable d'y faire un 1./3. J'ai lu (sur ce forum mais je ne sais plus où) que par défaut, ce sont des doubles qui sont utilisés, il n'y aura donc pas de pb d'ambiguité de prototype de fonction entre (cf man sqrt)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double sqrt (double x);
    float sqrt (float x);
    long double sqrt (long double x);

  4. #4
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Le préprocesseur ne fait que du remplacement de texte. Un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define SIX 4+2
    int a = 2*SIX;
    donnera après passage de préprocesseur (mais avant compilation) le code suivant :
    Par contre le compilateur devrait se rendre compte que 2*4+2 est calculable imédiatement et le remplacer par 10.

    Dans ton exemple, le compilateur ne pourra pas faire le calcul car il y a appel à une fonction (sqrt). Et cette fonction sera appelée à chaque utilisation de SQRT2 ou CST1 (pas efficace).

    D'autre part, tu vois bien sur mon exemple l'un des principaux pièges de préprocesseur. 2*SIX ne vaut pas 12...


    Edit : le compilateur sait faire des calculs (c'est en partie son boulot), mais il ne peut pas utiliser la fonction sqrt car c'est un *compilateur* et pas un interpréteur/émulateur/... Rien ne lui dit que la fonction sqrt est déterministe, tu peux imaginer qu'elle retourne la racine positive ou négative en fonction d'une variable globale par exemple.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    OK je comprends. Merci


  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par salseropom
    Bonjour, j'ai peur de poser une question un peu bête, mais j'aimerais en avoir le coeur net : est-ce que si je fais un calcul dans un #define, sera-t-il sera effectué lors de la compilation ? Je m'explique, je désire faire la chose suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2 sqrt(2.)
    #define CST1 -3./SQRT2
    dans lors de la compilation, dès qu'il y a un SQRT2 ou un CST1, l'expression sera remplacée par sqrt(2.) et par -3./sqrt(2.). Mais dois-je plutôt écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define SQRT2  1.414213562373095
    #define CST1 -2.121320343559642  /* -3/sqrt(2.) */
    pour être sûr que le code remplacé contiendra les valeurs numériques et non le calcul à refaire à chaque fois ? Je pense que les compilo doivent être suffisament développés pour faire cette optimisation tout seul (dois-je rajouter des options ?) mais j'aimerais en avoir le coeur net.

    Autre question, d'un point de vu lisibilité, que vaut-il mieux faire : faire un fichie defines.h qui contient tous mes #define et que j'inclus donc dans chaque fichier source ou bien n'écrie que les #define correspondants à chaque fichier source ?

    Merci.
    Le problème, c'est qu'il y a appel d'une fonction externe i.e. sqrt(). Le calcul de la racine correspondante ne pourra pas avoir lieu à la compilation, car l'édition des liens n'aura pas encore eu lieu...

    Notons qu'avec gcc et l'attribut __attribute__((const)), il y a possibilité d'optimiser un appel multiple à sqrt(2.) (Voir: http://www.unixwiz.net/techtips/gnu-...tes.html#const ). Peut-être que la GNU libc déclare la fonction sqrt() avec cet attribut... (j'ai pas vérifié)

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 64
    Par défaut
    Je ne sais pas si cela peut etre utile.

    # define SQ(x) ((x) * (x))

    met fais un carre (je sais la lib math le fais mais j'avais pas le droit de l'utiliser a l'epoque donc je me suis fais une operation )

    Peut etre que si tu te debrouille bien tu peux peut etre trouver une equivalence pour ton calcul ^^ mais j'en doute...

    A bientot

  8. #8
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par PiXi-PiX
    # define SQ(x) ((x) * (x))
    Ce qui permet de mettre en avant un autre gros piège du préprocesseur, quand tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int a = 5;
    int b = SQ(++a);
    Deux fonctions (pour les entiers et pour les flottants) seront beaucoup plus sûres.
    Citation Envoyé par PiXi-PiX
    Le calcul de la racine correspondante ne pourra pas avoir lieu à la compilation, car l'édition des liens n'aura pas encore eu lieu...
    Ce n'est pas qu'un problème d'édition de lien, mais lié au fait que rien ne dit que le résultat soit déterministe (cf. exemple plus haut).

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

Discussions similaires

  1. Des calculs dans une base de données
    Par elharrak dans le forum NetBeans
    Réponses: 1
    Dernier message: 19/06/2012, 16h30
  2. Effectuer des calculs dans un cube.
    Par baccarios dans le forum SSAS
    Réponses: 2
    Dernier message: 27/04/2010, 10h35
  3. Insérer des calculs dans une page HTML
    Par cassiopee64 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 17/10/2009, 12h46
  4. Effectuer des calculs dans un ordre précis
    Par missoly dans le forum VBA Access
    Réponses: 5
    Dernier message: 17/07/2008, 15h57
  5. Effectuer des calculs dans des zones de texte
    Par flagfight dans le forum IHM
    Réponses: 3
    Dernier message: 07/07/2006, 16h01

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