Perte de precision dans la division

Fermé
MMAMustapha - Modifié par Chris 94 le 20/01/2017 à 02:33
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 - 22 janv. 2017 à 08:42
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

yg_be Messages postés 23346 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 24 novembre 2024 Ambassadeur 1 552
20 janv. 2017 à 07:37
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
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
20 janv. 2017 à 16:25
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
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
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
22 janv. 2017 à 08:42
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