Partage
  • Partager sur Facebook
  • Partager sur Twitter

Qu'est-ce qui ne va pas dans mon XOR ?

Sujet résolu
    17 mars 2019 à 11:14:10

    Bonjour a tous,

    j'apprends le c++ depuis peu sur code::block en suivant le cours dans zeste de savoir, et je suis un peu bloquer par un des exercices de fin de chapitre qui demande de faire un XOR. J'ai déjà réussi a comprendre a peu prés la logique de comment passer de la table de vérité a l'écriture en code  (merci mon frère en école d'ingénieur), et le résultat est a peu prêt correct : false et false donnent bien un false, ainsi que true et true, le problème vient de quand j'ai un true, et un false.

    Voici mon code

    #include <iostream>
    
    int main()
    {
        bool const a(false);
        bool const b(true);
        std::cout << std::boolalpha;
        std::cout << a << " " << b << std::endl; //affiche d'abord a et b
    
        std::cout << (a && !b) || (b && !a); //affiche le XOR
        std::cout << std::endl;
    
        bool const deux_true { (true && !true) || (true && !true)};  //exemple zeste de savoir
        std::cout << "(true && !true) || (true && !true) == " << deux_true << std::endl; //exemple zeste de savoir
    
        return 0;
    }
    



    Mon problème étant :

    - quand "a" est false et "b" est true, le résultat est false (donc problème)

    MAIS

    -quand "a" est true et "b" est false, le résultat est true ( donc c'est bon !)

    J'ai essayer de le réécrire, mais je comprends pas pourquoi j'ai une erreur aussi particulière.

    Au passage, est-ce qu'il existe un opérateur logique XOR a écrire directement pour être moins fastidieux ?

    N'hésitez pas a me demander si il manque une information !

    -
    Edité par ClémentMiel 17 mars 2019 à 11:18:25

    • Partager sur Facebook
    • Partager sur Twitter
      17 mars 2019 à 11:38:03

      Bonjour,

      il manque des parenthèses

          std::cout  <<  ((a && !b) || (b && !a)); //affiche le XOR
      // sinon est compris comme si
          ( std::cout << (a && !b) )  ||  (b && !a);
      
      

      Et il existe l'opérateur xor, il y en a même 2, c'est ^ pour les bitfields ou bien != pour les booléens.

      bool a = true;
      bool b = false;
      bool result = (a != b); // sera vrai si un seul de a et b est vrai, c'est bien un XOR




      • Partager sur Facebook
      • Partager sur Twitter
      Bjarne Stroustrup : "C++ has become too expert friendly"
        17 mars 2019 à 11:54:02

        Effectivement, c’était les parenthèses ,merci ! Donc si j'ai bien compris, dans mon ancien programme, il se contente de Cout (a && !b) et ignore tout ce qui se trouve après, comme le || (b && !a) ?

        Je ne sais pas encore ce que'est un bitfield, mais c'est vraiment une superbe solution pour le Xor, merci beaucoup !

        • Partager sur Facebook
        • Partager sur Twitter
          17 mars 2019 à 14:57:08

          C++ est un petit peu paresseux ;)

          Si il se rend compte que l'évaluation de la partie gauche de l'expression fixe le résultat de l'évaluation, il ne perd pas son temps à évaluer la partie droite, puisqu'il connaît déjà le résultat final.

          C'est exactement ce qui se passe ici, cout << (a && !b), c'est le résultat de l'appel de l'opérateur  std::stream & operator << (std::stream & , bool) qui va dire si on continue l'évaluation, or un std::stream est par convention évalué à false, uniquement lorsqu'il est invalide ou en erreur.

          Le fait de vouloir écrire un booléen sur la sortie standard ayant fort peu de chances de mettre celle-ci en erreur, le premier terme de l'expression sera (presque) toujours true et donc pas besoin d'évaluer le second terme, puisque quelle que soit sa valeur ça ne changera pas le résultat final.  

          • Partager sur Facebook
          • Partager sur Twitter
          Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
            17 mars 2019 à 16:26:36

            Merci pour la réponse int21h ! C'est un peu au dessus de mes connaissances, mais je pense comprendre le principe, merci encore a toi :D
            • Partager sur Facebook
            • Partager sur Twitter
              17 mars 2019 à 18:51:38

              Pour éclaircir peut être un peu <<, &&, ||, +,-... sont ce que l'on appelle des opérateurs ( exactement comme en math, quelle coïncidence ^^ ). Ces opérateurs sont en fait des fonctions déguisées.

              Si tu voulais être ultra rigoureux tu n'écrirais pas

              std::cout << "coucou";

              mais 

              operator << (std::cout,"coucou");

              Je te rassure tout de suite, personne n'emploie jamais la deuxième forme, sauf dans notre cas précis où il s'agit de te montrer que l'emploi de cout se résume à un appel de la fonction operator <<(...). Il en va de même pour tous les opérateurs, ce sont des fonctions, et ce petit détail ouvre un champs de possibilités assez intéressant: comme ce sont des fonctions, on peut les surcharger (presque tous). Ce n'est pas très important à ton niveau, mais garde ça pour plus tard, à un moment dans ton apprentissage, on te parlera de surcharge de fonction puis d'opérateur et là tout deviendra clair ;)

              -
              Edité par int21h 17 mars 2019 à 18:54:20

              • Partager sur Facebook
              • Partager sur Twitter
              Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug

              Qu'est-ce qui ne va pas dans mon XOR ?

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown