Problème avec fonction pow

Problème avec fonction pow - C - Programmation

Marsh Posté le 11-12-2013 à 19:40:35    

..

Message cité 1 fois
Message édité par jeje934 le 13-12-2013 à 12:01:56
Reply

Marsh Posté le 11-12-2013 à 19:40:35   

Reply

Marsh Posté le 11-12-2013 à 21:38:55    

Petite question : tu peux donner le type de tes variables (int, long, double, ??? )... J'ai l'intuition que ça vient de là.  

Reply

Marsh Posté le 11-12-2013 à 23:42:47    

Bonsoir, voici un screen avec toute les variables :)  Merci

 


Message édité par jeje934 le 13-12-2013 à 12:00:52
Reply

Marsh Posté le 12-12-2013 à 14:15:43    

C'est beaucoup moins lisible que si le code était posté ici.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-12-2013 à 15:37:02    

...


Message édité par jeje934 le 13-12-2013 à 12:01:16
Reply

Marsh Posté le 12-12-2013 à 20:33:00    

Moué, bienvenue dans le monde merveilleux des calculs flottants. Ton problème est dû à une perte de précision et une mauvaise méthode d'arrondie, plus particulièrement dans cette expression :

Code :
  1. nombre = nombre - result[i] * pow(10,i);


 
C'est d'autant plus la merde que même si tu regardes dans un débuggeur / ajoute des printf() un peu partout, tu ne verras sans doute aucun problème.
 
Ton problème vient néanmoins du fait que pow() renvoie un double, qui promouvera toute l'expression avec des calculs flottants. Ces calculs flottants seront fait par le FPU, qui utilise une plus grande précision que les doubles (80bits au lieu de 64).
 
Lorsque j'essaie avec le nombre 123456, l'expression devient :

Code :
  1. 123456 - 1 * pow(10, 5) = 0xfcffffffffff3fb70d40


(Le résultat est imprimé en hexa, parce que je n'ai pas trouvé de méthode fiable pour imprimer la valeur exacte d'un "long double" ). La série de fffffff semble indiquer que la valeur n'est pas exacte. Valeur qui est arrondie lorsque convertie en double (0x0000000000e8d640), on voit que la mantisse contient une valeur exacte. Ça veut dire qu'en interne le résultat de cette expression est probablement 23455.999999999999999999999, arrondie par défaut donc 23455.
 
Assez technique comme problème, et absolument pas intuitif. Deux façons de corriger ça :

  • Utilise la fonction round(), du style: nombre = round(nombre - result[i] * pow(10,i));
  • Utilise des calculs entiers (conseillé). Va falloir changer légèrement la logique, mais rien de dramatique.

Reply

Marsh Posté le 13-12-2013 à 11:49:48    

Merci c'est cool ça marche à présent <! :)

Reply

Marsh Posté le 13-12-2013 à 15:57:05    


 
Bonjour,
 
Pourquoi effacez vous vos posts une fois la solution donnée ?
C'est un forum sur la programmation, d'autres personnes seraient ravies de comprendre le contexte si elles sont confrontées au même problème, quant bien même si le problème venait d'un exercice scolaire.


Message édité par honrisse le 13-12-2013 à 16:00:47
Reply

Marsh Posté le 16-12-2013 à 17:15:57    

[:prozac] Mais pourquoi as-tu tout viré ? Il était loin d'être évident ton problème... Juste histoire de garder une trace pour les générations futures, le code était :

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. int main()
  5. {
  6. //    int basedepart;
  7.     int nombre, l, d;
  8.     printf("Entrez nombre : " );
  9.     scanf("%d", &nombre);
  10.     printf("Valeur : %d\n", nombre);
  11. //    printf("Base de depart : " );
  12. //    scanf("%d", &basedepart);
  13.  
  14.     l = 1;
  15.     d = 10;
  16.     while ((nombre/d) != 0)
  17.     {
  18.         l++; //nbr de chiffre
  19.         d*=10;
  20.     }
  21.     printf("%d\n", l); //affiche nombre de chiffres dans le nombre
  22.  
  23.     int i;
  24.     int result[l]; //l=nombre de chiffre
  25.  
  26.     for (i = l-1; i >= 0; i--) // remplissage tableau avec les chiffres
  27.     {
  28.         result[i] = nombre / pow(10,i);
  29.         nombre = nombre - result[i] * pow(10,i);
  30.  
  31.         printf("Valeur case %d : %d\n" ,i,result[i]);
  32.     }
  33.     return 0;
  34. }

Reply

Marsh Posté le 16-12-2013 à 20:59:59    

Non,ce n'est pas de l'égoisme, j'avais prévue de le remettre après le six janvier, en effet il s'agit dune partie de code pour un devoir maison noté, le prof étant suspicieux c'était pour éviter qu'il pense qu'on a copié le code du net et accessoirement que des gens de la promo copie également le code

Reply

Marsh Posté le 16-12-2013 à 20:59:59   

Reply

Marsh Posté le 16-12-2013 à 21:41:45    

Hmm, je crois que tu es un peu trop parano là. Je ne pense pas que ton prof pourra te reprocher quoi que ce soit. Ce n'est pas comme si tu avais débarqué sur ce forum, en balançant: faites mon exo, je ramasse les copies dans 2 heures, LOL. Il y a un risque que quelqu'un copie ton code, c'est sûr, mais le but de tout exo, c'est avant tout de comprendre un concept, plus que de pondre du code.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed