Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur d'égalité triviale

    11 octobre 2020 à 20:07:04

    Bonjour, je suis entrain de m'entraîner à utiliser les structures. J'ai réalisé ce petit programme qui affiche la norme de mon vecteur puis affiche si le vecteur est normalisé ou non. Cependant, lorsque le programme s’exécute il m'affiche dans l'ordre "1" puis "0", ce qui se traduit par "la norme du vecteur vaut 1" et "le vecteur n'est pas normalisé". Ces' contradictoire, je ne trouve pas mon erreur. J'ai bien fait attention de comparer deux double pour éviter les erreurs d'arrondis mais ce n'est pas le problème ici apparemment. Pouvez-vous m'aider ?

    • Partager sur Facebook
    • Partager sur Twitter
      11 octobre 2020 à 20:21:35

      C'est normal, il y a toujours des imprécisions autour des doubles: https://stackoverflow.com/a/4010279/15934

      PS: `func(v) == 1.0` vaut déjà true ou false. Pas besoin de rajouter une couche d'opération ternaire.

      PPS: Préfères <cmath> en C++, il y a plus de choses dedans.

      PPPS: Préfère copier-coller le code plutôt que d'utiliser des images.

      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        11 octobre 2020 à 21:19:31

        lmghs a écrit:

        C'est normal, il y a toujours des imprécisions autour des doubles: https://stackoverflow.com/a/4010279/15934

        PS: `func(v) == 1.0` vaut déjà true ou false. Pas besoin de rajouter une couche d'opération ternaire.

        PPS: Préfères <cmath> en C++, il y a plus de choses dedans.

        PPPS: Préfère copier-coller le code plutôt que d'utiliser des images.



        Merci beaucoup pour ces conseilles.

        -
        Edité par LeTesla 11 octobre 2020 à 21:25:51

        • Partager sur Facebook
        • Partager sur Twitter
          11 octobre 2020 à 21:36:00

          Bonjour,

          Merci de colorer votre code à l'aide du bouton Code

          Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: cpp;">Votre code ici</pre>.

          Merci de modifier votre message d'origine en fonction.

          Liens conseillés

          • Partager sur Facebook
          • Partager sur Twitter
            11 octobre 2020 à 22:56:20

            Bonjour,

            Si tu affiches la valeur norme-1 tu verras que tu obtiens un nombre très très proche de 1 mais ça n'est pas 1.

            	std::cout << "norme-1 = " << Vecteur3DGetNorme(v)-1 << std::endl;
            

            Tu peux améliorer la précision de ton calcul en utilisant la fonction std::hypot() plutôt qu'une racine de somme de carrés, elle fait la même chose mais évitant la perte de précision de génère les carrés. Ça nécessite le C++17 et d'utiliser #include <cmath> plutôt que #include <math.h>.

            double  Vecteur3DGetNorme( const Vecteur3D&  v ) {
            	// return std::sqrt( v.x*v.x + v.y*v.y + v.z*v.z );
            	return  std::hypot( v.x , v.y , v.z );  // plus précis
            }

            Ça devrait résoudre le cas de ton vecteur, mais ça n'est pas suffisant pour d'autres. On doit vérifier que le nombre obtenu est très proche de 1 (donc doit être entre 1 moins un chouia et 1 plus un chouia). Le plus petit nombre que l'on peut ajouter à 1 est indiqué par la bibliothèque standard, il s'appelle epsilon et est fourni dans l'include <limits>. On peut supposer une erreur de quelques epsilon. On peut écrire:

            bool  Vecteur3DEstNormalise( Vecteur3D const&  v ) {
            	return std::abs( Vecteur3DGetNorme(v) - 1 ) < 4 * std::numeric_limits<double>::epsilon();
            }

            -
            Edité par Dalfab 11 octobre 2020 à 22:58:49

            • Partager sur Facebook
            • Partager sur Twitter

            En recherche d'emploi.

              11 octobre 2020 à 23:23:54

              > std::hypot( v.x , v.y , v.z );  // plus précis

              La dernière fois que j'ai regardé les implémentations de GCC et de LLVM faisaient les 3 carrées, les additions et la racine carrée. Cela peut avoir changé depuis.

              (Pour GCC qui implémentait vraiment la version plus précise pour la dimension 2, c'était bien plus lent.)

              • Partager sur Facebook
              • Partager sur Twitter
              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

              Erreur d'égalité triviale

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown