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 :

Problème avec la fonction pow(les puissance)


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 18
    Points : 16
    Points
    16
    Par défaut Problème avec la fonction pow(les puissance)
    Bonjour a tous

    j'ai un petit pb avec la fonction pow pour calculer les puissances.
    par exemple quand dans mon code je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int result = 0;
    result = pow(10, 2);
     
    printf("%ld", result);
    Sa marche
    mais quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("%ld", pow(10, 2));
    Sa marche pas

    J'arrive pas a comprendre pk et sa fais plein d'erreur dans mon programme

    merci pour votre aide

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Prototype de pow :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           double pow(double x, double y);
    Dans ton premier code, il fait un cast vers le type entier donc si le résultat est entier, tout fonctionnera (bien que tu devrais mettre %d et non %ld...)


    Dans le deuxième code, aucun cast n'est fait et un compilateur correctement paramétré devrait te sortir un message de warning pour prêvenir que ce que tu donnes à printf et ce que tu lui dit sont deux choses distinctes...

    Jc

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    fearyourself
    Dans le deuxième code, aucun cast n'est fait et un compilateur correctement paramétré devrait te sortir un message de warning pour prêvenir que ce que tu donnes à printf et ce que tu lui dit sont deux choses distinctes...
    Je ne crois pas que les compilateurs vont jusqu'à analyser la chaîne de format pour vérifier leur concordance avec les paramètres qui sont donnés au printf. Le prototype de printf ne permet pas de telles vérifications.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    GCC le fait, utilisant une extension appelee __printflike.
    La c*nnerie majeure de certaines versions (j'ignore si c'est toujours le cas), c'est qu'il accepte seulement un void* pour %p, plutôt que NimporteQuoi *...

    (enfin, ça a peut-être été résolu depuis)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par diogene
    fearyourself Je ne crois pas que les compilateurs vont jusqu'à analyser la chaîne de format pour vérifier leur concordance avec les paramètres qui sont donnés au printf. Le prototype de printf ne permet pas de telles vérifications.
    Certains le font. Pourquoi ne le feraient-ils pas ? Sont pas plus bêtes que nous...

    Pour gcc, je recommande : -Wall -Wextra -O2

    Ta vie va changer !
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    GCC le fait, utilisant une extension appelee __printflike.
    La c*nnerie majeure de certaines versions (j'ignore si c'est toujours le cas), c'est qu'il accepte seulement un void* pour %p, plutôt que NimporteQuoi *...

    (enfin, ça a peut-être été résolu depuis)
    J'espère que non. C'est la norme. "%p" attend un void*. Point. Si ce n'est pas le cas, cast obligatoire.

    Sachant que certains développeurs de gcc sont des gens du comité de normalisation, je ne m'en fais pas trop sur la comformité du gcc à la norme...
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Mais c'est débile!
    En C, ça augmente les risques de cast "sauvage" de n'importe quoi en void* !

    À quoi sert cette connerie?! Le type de destination n'est pas supposé agir sur la taille d'un pointeur!
    (à l'inverse des anciens modifieurs comme far et near)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    Mais c'est débile!
    En C, ça augmente les risques de cast "sauvage" de n'importe quoi en void* !

    À quoi sert cette connerie?! Le type de destination n'est pas supposé agir sur la taille d'un pointeur!
    (à l'inverse des anciens modifieurs comme far et near)
    Ils sont peut être anciens, mais ils existent toujours (je rappelle que tout processeur x86 boot en mode reel 16-bit)

    Le type par défaut des variadics est int. Si la variable n'a pas le bon type (il y a un risque avec NULL par exemple, qui peut être un int), il faut caster. Le choix s'est porté sur void * parce que c'est le plus neutre, je suppose...
    Comportement indéfini.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf ("%p\n", (void*) NULL);
    Correct.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Il n'y a pas de type par défaut pour les fonctions variadiques.

    En fait les fonctions variadiques se comportent comme les fonctions sans prototypes. Dans ce cas, les arguments subissent les conversions suivantes:
    - les valeurs des types plus petits que int sont convertis en int (ou en unsigned int si int n'est pas capable de représenter toutes les valeurs du type),
    - les floats sont convertis en doubles
    - les tableaux sont convertis en pointeur vers le premier élément du tableau.

    Et c'est tout. Les valeurs d'autres types sont passées telles quelles. Si c'est pas la valeur attendue par la fonction, c'est un comportement indéfini.

    Le problème avec les pointeurs, c'est que la norme autorise la représentation des pointeurs à différer suivant le type pointé, même la taille peut changer. En particulier, il y a eu des architectures où la représentation naturelle d'un char* prend plus de place que les autres pointeurs (elle comporte deux parties: un pointeurs vers un mot et l'indicie du caractère dans le mot, parfois aussi la taille du byte comme sur un PDP-10). La seule contrainte qu'il y ait, c'est que void* et char* doivent tout deux être capables de contenir les valeurs des autres pointeurs (mais pas nécessairement la représentation). Donc quand on passe un pointeur à une fonction sans prototype ou à une fonction variadique, il est passé tel quel. Si la fonction attends un void*, le compilateur n'en sait officiellement rien -- gcc le sait pour certaines d'entre elle et averti du problème -- et ne peut pas effectuer une conversion. (Dans la plupart des cas de nos jours, la conversion est la fonction identité.)

    Le problème avec NULL, c'est que la norme autorise pas mal de types pour la valeur de NULL: tous les types entiers et void*. Dans les contextes où le type désiré est connu, il y a conversion implicite. Dans le cas des appels de fonctions sans prototype ou de fonctions variadiques, il faut convertir. Pourquoi est-ce que la norme permet plusieurs choix? Pour respecter l'existant au moment où elle a été écrite. Traditionnellement, la valeur était 0 (donc un int). Quand on s'est retrouvé avec des pointeurs sur 32 bits mais des int sur 16 bits, le code qui passait NULL à des fonctions variadiques ou sans prototype sans le convertir dans le bon type a eu des problèmes. Pour éviter les plaintes de leurs clients, certains vendeurs ont utilisé 0L comme définition pour NULL (je ne suis pas sûr que void* existait déjà, et de toute manière dans du vieux code on voit parfois utiliser NULL pour autre chose que des pointeurs) ou (void*).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par diogene
    fearyourself Je ne crois pas que les compilateurs vont jusqu'à analyser la chaîne de format pour vérifier leur concordance avec les paramètres qui sont donnés au printf. Le prototype de printf ne permet pas de telles vérifications.
    Juste pour conclure ceci avec un exemple, utilisant :

    gcc version 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
    et le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        int i=3;
        double d=4.0;
        float f = 3.2;
        float *pf = &f;
     
        printf("%f %p %d %p\n",i,d,f,pf);
        return EXIT_SUCCESS;
    }
    Me donne ceci :

    ~/tmp$ gcc -Wall -Wextra -O2 testprintf.c
    testprintf.c: In function 'main':
    testprintf.c:11: warning: format '%f' expects type 'double', but argument 2 has type 'int'
    testprintf.c:11: warning: format '%p' expects type 'void *', but argument 3 has type 'double'
    testprintf.c:11: warning: format '%d' expects type 'int', but argument 4 has type 'double'
    Jc

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Il n'y a pas de type par défaut pour les fonctions variadiques.
    Oui, j'ai abusivement simplifié. Désolé.

    Merci pour les précisions.
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. Problème avec la fonction pow
    Par marguerite99 dans le forum C
    Réponses: 13
    Dernier message: 14/11/2009, 14h25
  2. Réponses: 1
    Dernier message: 25/02/2009, 09h44
  3. [MySQL] Problème avec la fonction fgets et les retours chariot
    Par didoulive dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 20/02/2008, 19h08
  4. problème avec la fonction pow()
    Par emprex dans le forum C
    Réponses: 7
    Dernier message: 17/11/2007, 12h04
  5. probléme avec la fonction pow
    Par arglow dans le forum C
    Réponses: 7
    Dernier message: 23/07/2007, 13h38

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