If() et les nombres à virgules

Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005 - 3 févr. 2004 à 22:14
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005 - 8 févr. 2004 à 16:26
Bonjour,
J'ai un prog qui tourne comme ceci : il élève un nombre x à une puissance n et la compare avec une équation contraire (n puissance x). Les X sont increnmenté nomalement (x=x+interval;).
Tout fonctionne très bien avec un interval entier ou qui est dans la suite 0.5/2, 0.5/4 ....
Mais avec un interval de 0.1 : aucune solution alors que j'ai entré exactment les meme données !!!!!

Comment faut-il faire pour résoudre ce problème ?
Mes variables sont des float (j'ai essayé avec double, ca change rien...)

Jolfulorc,
Qui vous remercie d'avance :)

11 réponses

hilairenicolas Messages postés 398 Date d'inscription jeudi 30 octobre 2003 Statut Membre Dernière intervention 15 juin 2007 2
4 févr. 2004 à 09:21
La je pense qu'il serait temps de nous montrer un bout de code
0
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
4 févr. 2004 à 14:50
le voilà en entier (il n'est pas long, ne vous en fait pas :D)
#include <stdio.h>
#include 
#include <math.h>

int main()
{
  float x, max, resultat, resultat2, intervalle, equation, nbres=0;
 
  cout<<"|------------------------|\n| Math2\t: Equations supp |\n|------------------------|";
  getchar();
  
  cout<<"\nRecherche des X pour l'equation n^x = x^n ...\nVeuillez taper le nombre N (N+) : ";
  cin>>equation;
  
  cout<<"Veuillez taper le nombre max de la serie (N+) : ";
  cin>>max;
  
  cout<<"Veuillez taper le nombre min de la serie (N-) : ";
  cin>>x;
  
  cout<<"Veuillez taper le nombre d'intervalle dans la serie (R+) : ";
  cin>>intervalle;
  cout<<"--------------------------------------------------------"<<endl;
do { 
resultat = pow(x,equation);
resultat2 = pow(equation,x);if (resultat resultat2) { nbres++; cout<<"\nX "<<x<<"\t Resultat x^"<<equation<<" : "<<resultat<<"\t Resultat "<<equation<<"^x : "<<resultat2<<endl; }
cout<<x<<"\n";
x = x + intervalle;resultat resultat2 0;
} while (x < max+intervalle); 
  cout<<"\n--------------------------------------------------------"<<endl;
  
  cout<<"\nLe programme a tourve "<<nbres<<" solution(s) pour l'equation x^"<<equation<<" = "<<equation<<"^x"<<endl;

printf("\nAlors ? Heureux ?");
getchar(); getchar();
}


Merci,
Jolfulorc
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
5 févr. 2004 à 01:20
le test
if (resultat == resultat2)

est assez dangeureux avec des nombres à virgules. En effet, la représentation en mémoire est une troncature des nombres rééls. De plus, les nombres sont représentés en base 2 et pas 10. C'est pour ça que ça marche avec les nombres entiers et les intervales du type 0.5/2^n car dans ce cas les nombres ne sont pas tronqués. Par contre 0.1 (1/10) est arrondi en base 2 de la même façon que 1/3 en base 10.

Au lieu de faire un test d'égalite, fait un test avec une marge d'erreur (0.0001 ou 0.00001 par exemple).
0
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
5 févr. 2004 à 13:03
Ok, merci bcp
Jolfulorc
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
5 févr. 2004 à 13:16
lol, mais tu ne pourrais pas me montrer un exemple de test de marge d'erreur ? J'arrive pas à en trouver en plus c'est assez urgent :big)

Merci d'avance ...
Jolfulorc
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
5 févr. 2004 à 21:21
float val1;
float val2
float err = 0.0001f;

marge absolue :
if(fabs(val1-val2)<err)
{
//val1 et val2 égaux à 0.0001 près
}

marge relative (tester si égaux à 0 avant de faire la division):
if(fabs(val1-val2)/val1 < err)
{
// val1 et val2 égaux à un pourcentage près
}

à toi de faire des tests pour voir ce qui est le mieux.
0
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
6 févr. 2004 à 16:08
Merci bcp pour la technique, mais ca change rien au résultat, toujours aucun résultat !
Jolfulorc
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
6 févr. 2004 à 16:50
Peux-tu me mettre un exemple qui est censé donner un résultat et que le prog ne trouve pas ?
0
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
8 févr. 2004 à 10:18
Vois par toi-même :
correct :

incorrect :

Jolfulorc
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 févr. 2004 à 14:38
On faisant le test :

float err = 0.00001f;
if (fabs(resultat-resultat2) < err)
{
}
on obtient les résultats mais il y a trop d'approximation (l'ajout de 0.1 à chaque itération et les calculs de pow accumulent les erreurs) du coup pour x 2 on obtient N^x 3.99999 (érreur de 1e-6 par raport à la valeur attendue).

en passant avec des double, l'erreur n'est plus que de 1e-15 mais les valeurs ne sont toujours pas strictement égales. Il faudra donc effectuer le test avec écart absolu.
double err = 1e-9;
if (fabs(resultat-resultat2) < err)
{
}
0
Jolfulorc Messages postés 15 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 14 mai 2005
8 févr. 2004 à 16:26
Ca fonctionne :D :-p Merci merci bcp !
Jolfulorc
0
Rejoignez-nous