Perte de precision dans la division

MMAMustapha -  
Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   -
Salut, j'ai un probleme avec une comparaison qui ne marche pas.
besoin de votre aide
#include <iostream>
using namespace std;
int main()
{
    float y;
    y=1/(1/float(2)-1/float(3));
    cout<<y<<"\t"<<"normalement y==int(y) ... mais ..."<<endl;
    if (y==int(y))
        cout<<"cool"<<endl;
    else
        cout<<"ne marche pas"<<endl;
    y=1/float(2)+1/float(2);
    cout<<y<<endl;
    if (y==int(y))
        cout<<"now it works!!!!!"<<endl;
    return 0;
}

4 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    bonjour. quel est ton problème: as-tu une erreur de compilation? laquelle?
    si ton programme ne donne pas le résultat que tu attends, peux-tu nous expliquer le résultat obtenu et le résultat attendu?
    que pourrais-tu faire de plus pour comprendre ce que fait ton programme?
    as-tu essayé de faire ces calculs avec une calculatrice, pour comparer?
    0
  2. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Bonjour,
    Il ne faut pas confondre mathématiques et informatique.
    En math 1/2 - 1/3 vaut 1/6.
    En informatique, les nombres ne sont généralement pas des nombres réels mais des approximations, on aura 1.0/2.0 - 1.0/3.0 vaut environ 1.0/6.0.
    Exemple :
    if ( 1.f + 0.0000000001f == 1.f )       // vrai!
    cout << 1e-45f * 100;                   // affiche 1.401e-43!
    D'où la règle : ne jamais faire un test d'égalité sur un float ou un double
    0
  3. MMAMustapha
     
    yg-ben j crois que tout est expliqué dans le code source,
    dalfan j comprends maintenant, merci. Mais y a t il ps des méthodes pour comparer, j'en ai bien besoin dans un programme
    0
  4. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Avec des float et double à cause de l'imprécision tout test d'égalité est un problème.
    • On le résout le plus souvent en évitant les flottants et en posant le test différemment; par exemple, est-ce que : ( x / (float)y ) est un entier? devient est-ce que : x % y est nul?
    • On peut aussi utiliser une bibliothèque (ou créer ses propres objets) qui évite les flottants. Par exemple avec un type 'Fraction' qui évite des divisions.
    • Sinon on peut toujours effectuer des tests d'inégalité, par exemple, if (x > 5.9 && x < 6.1) // pour un x proche de 6.
    • On peut créer une fonction qui effectue ce genre de test (ici template pour gérer float et double)
      template<class T> inline bool quasi_egaux(T const& x , T const& y) {
        return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y)
              || std::abs(x-y) < std::numeric_limits<T>::min();
      }
      Elle accepte une erreur de 2 bits de précision. Mais c'est rarement un bon moyen.
    0