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 :

int, unsigned int, et la fonction pow


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 int, unsigned int, et la fonction pow
    Bonjour, je suis tombé sur un pb. J'arrive à l'identifier et à le corriger, mais je ne sais pas pourquoi ce que j'ai fait fonctionne. Voici mon programme (archi simple) :

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    int main()
    {
      int n=10,k=1;
      double b=2.,auxb=(b-1.)/b,aux1=pow(b,k);
      double aux2=pow(b,k-n)/(sqrt((1.+auxb*k)*aux1));
     
      printf("aux2 = %f\n",aux2); 
     
      return EXIT_SUCCESS;
    }
    la sortie est

    aux2 = 0.001128
    tout va bien. Maintenant, je me suis dit que k et n étaient > 0 donc je vais les modifier en mettant un unsigned devant (en fait, à terme, j'aurais des unsigned long long int car j'aurais de très grands entiers). Voici mon nouveau prgm (je n'ai que modifié la première ligne du main en y ajoutant un unsigned)

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    int main()
    {
      unsigned int n=10,k=1;
      double b=2.,auxb=(b-1.)/b,aux1=pow(b,k);
      double aux2=pow(b,k-n)/(sqrt((1.+auxb*k)*aux1));
     
      printf("aux2 = %f\n",aux2); 
     
      return EXIT_SUCCESS;
    }
    et là, la sortie est

    aux2 = inf
    ce qui ne vas pas du tout. Donc pour corriger je dois faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    double aux2=pow(b,(double) k-n)/(sqrt((1.+auxb*k)*aux1));
    Quand j'affiche k-n il me renvoie -9. Certes, ce sont des unsigned donc le problème vient de là (enfin je pense). Pourquoi la conversion de l'entier k-n en double n'est-elle pas automatique ? man pow me dit que la fonction pow prend deux doubles en entrée.

    Merci.

  2. #2
    Membre confirmé Avatar de Dev-FX
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 94
    Par défaut
    Salut,

    Tu touches ici le grand probleme du langage C (ou limites) ,il est limité a (2^32) - 1, si tu veux allez plus loin il faut faire un effort !!
    Essaie avec la fonction factorielle par exemple .
    Sinon , je parle pas de la manipulation des chaines de caracteres.......

    Merci .

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Dev-FX
    Tu touches ici le grand probleme du langage C (ou limites) ,il est limité a (2^32) - 1, si tu veux allez plus loin il faut faire un effort !!
    Essaie avec la fonction factorielle par exemple .
    Sinon , je parle pas de la manipulation des chaines de caracteres.......
    Portnawak...

  4. #4
    Membre confirmé
    Inscrit en
    Octobre 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 123
    Par défaut
    boulalalalala.... c'est du C c'est pas du MatLab... j'rigole...il faut savoir que le C est très "strict"...donc si une fonction te demande un double, ne lui mets pas un unsigned int...

    Exemple concret : Imagine tu es au resto avec ta femme, tu commandes des carottes RAPEES et le serveur t'apporte une carotte entiere toute pleine de terre, si tu la laves et la rapes tu peux la manger mais ce n'est pas ce que tu attendais de la part du resto???!! Eh ben là c'est pareil, la fonction te demande un double donc donne-lui un double...c'est logique,nan?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par salseropom
    Quand j'affiche k-n il me renvoie -9. Certes, ce sont des unsigned donc le problème vient de là (enfin je pense). Pourquoi la conversion de l'entier k-n en double n'est-elle pas automatique ? man pow me dit que la fonction pow prend deux doubles en entrée.
    Ben oui. tu fais une différence entre 2 unsigned, et celle-ci est négative. Résultat, un unsigned énorme !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
     
    int main(void)
    {
       unsigned int n=10,k=1;
       printf("k-n = %u\n", k - n);
     
      return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    k-n = 4294967287
     
    Press ENTER to continue.
    Cette valeur est convertie automatiquement en double par pow() et c'est le drame.

    Soit tu laisses int, soit tu castes en int avant de passer à pow() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double aux2=pow(b,(int)(k-n))/(sqrt((1.+auxb*k)*aux1));

  6. #6
    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
    Citation Envoyé par Emmanuel Delahaye
    Ben oui. tu fais une différence entre 2 unsigned, et celle-ci est négative. Résultat, un unsigned énorme !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
     
    int main(void)
    {
       unsigned int n=10,k=1;
       printf("k-n = %u\n", k - n);
     
      return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    k-n = 4294967287
     
    Press ENTER to continue.
    Cette valeur est convertie automatiquement en double par pow() et c'est le drame.

    Soit tu laisses int, soit tu castes en int avant de passer à pow() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double aux2=pow(b,(int)(k-n))/(sqrt((1.+auxb*k)*aux1));

    Salut, oui je m'attendais à ce genre d'explication. Mais je ne comprends pas très bien le fonctionnement du compilo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    k-n = 4294967287
     
    Press ENTER to continue.
    donc si je cast k-n en double

    pourquoi aurai-je -9 (ce que je veux car je rappelle que k==1 et n==10) et non 4294967287 ? Est-ce que le cast en double, transforme AVANT d'effectuer le calcul k et n en double (ce que je pense vu lesrésultats) ?

    Merci.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par salseropom
    Salut, oui je m'attendais à ce genre d'explication. Mais je ne comprends pas très bien le fonctionnement du compilo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    k-n = 4294967287
     
    Press ENTER to continue.
    donc si je cast k-n en double

    pourquoi aurai-je -9 (ce que je veux car je rappelle que k==1 et n==10) et non 4294967287 ? Est-ce que le cast en double, transforme AVANT d'effectuer le calcul k et n en double (ce que je pense vu lesrésultats) ?
    Ce que tu as fait a converti un des éléments en double, ce qui a automatiquement indiqué au compilateur de convertir tous les éléments de l'expression en double avant le calcul, conformément aux regles de promotion du langage C.

    Mais c'est lourdingue, c'est pourquoi le simple cast du résultat en int suffit comme je l'ai indiqué. La conversion int -> double est automatique car le prototype de la fonction a été fourni.

  8. #8
    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
    Citation Envoyé par Emmanuel Delahaye
    Mais c'est lourdingue, c'est pourquoi le simple cast du résultat en int suffit comme je l'ai indiqué. La conversion int -> double est automatique car le prototype de la fonction a été fourni.
    OK, je comprends mieux. Mais j'ai de très grands nombres donc j'ai peur que la conversion en int me retourne un pb car il se peut que je dépasse MAX_INT. Je me suis donc dit que passer en double me laissait plus de marge.

    Merci pour tous ces renseignements.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par salseropom
    OK, je comprends mieux. Mais j'ai de très grands nombres donc j'ai peur que la conversion en int me retourne un pb car il se peut que je dépasse MAX_INT. Je me suis donc dit que passer en double me laissait plus de marge.
    Déjà, il y a long et [C99] long long si nécessaire. Mais attention à ne pas exploser la fonction pow(). Tu as vu qu'on a vite fait de partir en INF avec un simple unsigned int.

    Garder aussi en tête qu'avec les doubles, on augmente la plage, mais c'est au prix de la perte de précision.

Discussions similaires

  1. Transformer (int année, int mois, int jour) en millisecondes
    Par Logic_613 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 24/04/2012, 11h08
  2. Réponses: 1
    Dernier message: 15/02/2007, 17h32
  3. Conversion int en string pour paramatre fonction
    Par Aliveli dans le forum Visual C++
    Réponses: 9
    Dernier message: 10/10/2006, 21h56
  4. int, unsigned char ou bool ?
    Par BNS dans le forum C++
    Réponses: 10
    Dernier message: 21/06/2006, 21h59
  5. [WMI] Variant de type Unsigned Int 64 ...
    Par phplive dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 09/05/2006, 20h15

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