[C, C++] Problème d'arrondis ...

Problème d'arrondis ... [C, C++] - C++ - Programmation

Marsh Posté le 22-12-2002 à 16:34:19    

Bonjour !
Voilà pour un programme de résolution du troisième degré je passe par une fonction qui résoud des équations du second degré...  
Mais j'ai un problème :)
Lorsque les valeurs traitées pas ma fonction qui résout le second degré sont assez proche de 0, le programme fonctionne mal. Au lieu de me renvoyer une racine réelle double, il me renvoit 2 racines réelles mais très peu défférentes (elles diffèrent à partir de 10^-5 environ). Du coup, ça ne va pas dans le bon cas dans la fonction qui résoud le troisième degré et ça ne fait pas ce qu'il faudrait.
 
Si quelqu'un pouvait m'aider pour ces galères d'arrondis, ce serait sympa !! :)
 
J'utilise uniquement des variables de type double.
 
Je ne mets pas de code, mais si vous voulez en voir une partie, pas de problème ...
 
Voilà, merci d'avance ! et bon dimanche  :sol:

Reply

Marsh Posté le 22-12-2002 à 16:34:19   

Reply

Marsh Posté le 22-12-2002 à 16:49:55    

Un peu de code (le coeur du traitement) et/ou exemple de données pourrait aider à saisir le problème.. :)  :jap:

Reply

Marsh Posté le 22-12-2002 à 17:01:37    

pour tester l'égalité avec des flottants, il faut toujours tester avec une marge :
 
 
#define epsilon 1e-5
 
float n = 4;
float f = tonCalcul();
 
 
if (f == n) // MAL
 
if (fabs(f -n) < epsilon) // OK
 
//
 
si tu veux de la précision '100%', tu devrais utiliser une classe qui représente les nombres symboliquement (par ex, racine de 2 divisé par 144)


Message édité par youdontcare le 22-12-2002 à 17:01:50
Reply

Marsh Posté le 22-12-2002 à 18:57:11    

y a les "long double" aussi sur 96bits


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 22-12-2002 à 19:13:06    

j'ai essayé en mettant que des "long double" et ça a rien changé ...
 
pour les classes on a pas encore appris :(

Reply

Marsh Posté le 22-12-2002 à 19:14:27    

ben si tu pouvais quand meme donner un peu de code....


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 22-12-2002 à 19:22:18    

Sioupli, un peu de code pour voir où ça coïnce. :sarcastic:

Reply

Marsh Posté le 22-12-2002 à 20:00:21    

vi désolé :D fallait manger ... ;)
 
bon ben je vous balance la coupable : ma fonction de résolution des équations du second degré ...
 

Code :
  1. int ResolDeuxieme(double a, double b, double c)
  2. {
  3. discr = b*b - 4*a*c;
  4. if (discr > 0)
  5. {
  6.  varRacine_deuxiemeX1Re = (-b-sqrt(discr))/(2*a);
  7.  varRacine_deuxiemeX2Re = (-b+sqrt(discr))/(2*a);
  8.  return 2;
  9. }
  10. else if (discr == 0)
  11. {
  12.  varRacine_deuxiemeX1Re = -b/(2*a);
  13.  return 3;
  14. }
  15. else
  16. {
  17.  if (b==0)
  18.  {
  19.   varRacine_deuxiemeX1Im = -sqrt(-discr)/(2*a);
  20.   varRacine_deuxiemeX2Im =  sqrt(-discr)/(2*a);
  21.   return 4;
  22.  }
  23.  else
  24.  {
  25.   varRacine_deuxiemeX1Re = -b/(2*a);
  26.   varRacine_deuxiemeX2Re = -b/(2*a);
  27.   varRacine_deuxiemeX1Im = -sqrt(-discr)/(2*a);
  28.   varRacine_deuxiemeX2Im =  sqrt(-discr)/(2*a);
  29.   return 6;
  30.  }
  31. }
  32. }


 
Voilà   :??:

Reply

Marsh Posté le 22-12-2002 à 20:02:58    

freeman_78 a écrit :

if (discr == 0)

et voilà ... à remplacer par un test avec marge, comme dit plus haut.

Reply

Marsh Posté le 22-12-2002 à 20:24:47    

oki alors je vais essayer ça :)
 
merci !!


Message édité par freeman_78 le 22-12-2002 à 20:25:00
Reply

Marsh Posté le 22-12-2002 à 20:24:47   

Reply

Marsh Posté le 22-12-2002 à 20:48:23    

la déclaration de discr a été "éludée" pour être plus clair ?
 
Y en a qui préfèrent préciser le caractère double ou float des "constantes" en mettant 0.0 et 2.0, mais d'autres disent que le compilateur est assez doué pour comprendre... sinon 0 serait int, 2 aussi.

Reply

Marsh Posté le 22-12-2002 à 20:48:30    

youdontcare a écrit :

pour tester l'égalité avec des flottants, il faut toujours tester avec une marge :
 
 
#define epsilon 1e-5
 
float n = 4;
float f = tonCalcul();
 
 
if (f == n) // MAL
 
if (fabs(f -n) < epsilon) // OK
 
//
 
si tu veux de la précision '100%', tu devrais utiliser une classe qui représente les nombres symboliquement (par ex, racine de 2 divisé par 144)

Code :
  1. if (fabs (f - n) <= epsilon * fabs (f))

Reply

Marsh Posté le 22-12-2002 à 23:51:00    

Merci à tous ! voilà ce que j'ai fait et qui fonctionne :

Code :
  1. int ResolDeuxieme(double a, double b, double c)
  2. {
  3. double epsilon;
  4. epsilon = 1e-3; //précision pour les discriminents proches de 0
  5. discr = b*b - 4*a*c;
  6. if (discr > epsilon)
  7. {
  8.  varRacine_deuxiemeX1Re = (-b-sqrt(discr))/(2*a);
  9.  varRacine_deuxiemeX2Re = (-b+sqrt(discr))/(2*a);
  10.  return 2;
  11. }
  12. else if (fabs(discr) <= epsilon)
  13. {
  14.  varRacine_deuxiemeX1Re = -b/(2*a);
  15.  return 3;
  16. }
  17. else
  18. {
  19.  if (b==0)
  20.  {
  21.   varRacine_deuxiemeX1Im = -sqrt(-discr)/(2*a);
  22.   varRacine_deuxiemeX2Im =  sqrt(-discr)/(2*a);
  23.   return 4;
  24.  }
  25.  else
  26.  {
  27.   varRacine_deuxiemeX1Re = -b/(2*a);
  28.   varRacine_deuxiemeX2Re = -b/(2*a);
  29.   varRacine_deuxiemeX1Im = -sqrt(-discr)/(2*a);
  30.   varRacine_deuxiemeX2Im =  sqrt(-discr)/(2*a);
  31.   return 6;
  32.  }
  33. }
  34. }


Message édité par freeman_78 le 22-12-2002 à 23:51:22
Reply

Marsh Posté le 23-12-2002 à 09:16:58    

il faut utiliser le test epsilon sur chaque test d'égalité.

Reply

Sujets relatifs:

Leave a Replay

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