Existe-t-il une telle chose? C'est la première fois que j'en rencontre un besoin pratique, mais je n'en vois aucun répertorié dans Stroustrup . J'ai l'intention d'écrire:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Mais il n'y a pas d' ^^
opérateur. Puis-je utiliser le bit ^
ici et obtenir la bonne réponse (quelle que soit la représentation machine de vrai et de faux)? Je ne mélange jamais &
et &&
, ou |
et ||
, j'hésite donc à le faire avec ^
et ^^
.
Je préfèrerais plutôt écrire ma propre bool XOR(bool,bool)
fonction.
Réponses:
L'
!=
opérateur sert cet objectif pour lesbool
valeurs.la source
bool
valeurs" car cela ne fait pas nécessairement ce que vous pourriez souhaiter pour les non-booléens. Et comme il s'agit de C ++, il existe un vraibool
type au lieu de devoir l'utiliserint
à cette fin.a
écrivez simplement!(a) != !(a)
Pour une véritable opération XOR logique, cela fonctionnera:
Notez que
!
sont là pour convertir les valeurs en booléens et les annuler, de sorte que deux entiers positifs inégaux (chacun atrue
) seraient évaluésfalse
.la source
!!
fonctionnerait juste demander bien, mais comme ils doivent être différents, les nier ne fait aucun mal.L' implémentation manuelle XOR logique appropriée dépend de la façon dont vous souhaitez imiter le comportement général des autres opérateurs logiques (
||
et&&
) avec votre XOR. Il y a deux choses importantes à propos de ces opérateurs: 1) ils garantissent l'évaluation des courts-circuits, 2) ils introduisent un point de séquence, 3) ils évaluent leurs opérandes une seule fois.L'évaluation XOR, comme vous le comprenez, ne peut pas être court-circuitée car le résultat dépend toujours des deux opérandes. Donc 1 est hors de question. Mais qu'en est-il de 2? Si vous ne vous souciez pas de 2, alors avec des
bool
valeurs normalisées (c'est-à-dire ), l'opérateur!=
fait le travail de XOR en termes de résultat. Et les opérandes peuvent être facilement normalisés avec unaire!
, si nécessaire. Implémente ainsi!A != !B
le XOR approprié à cet égard.Mais si vous vous souciez du point de séquence supplémentaire,
!=
ni le bit ni le bit^
n'est la bonne façon d'implémenter XOR. Une façon possible de faire XOR (a, b) correctement pourrait se présenter comme suitCeci est en fait aussi proche que possible de la fabrication d'un XOR maison "similaire" à
||
et&&
. Cela ne fonctionnera, bien sûr, que si vous implémentez votre XOR en tant que macro. Une fonction ne fonctionnera pas, car le séquencement ne s'appliquera pas aux arguments de la fonction.Quelqu'un pourrait dire cependant que la seule raison d'avoir un point de séquence à chacun
&&
et||
est de prendre en charge l'évaluation en court-circuit, et donc XOR n'en a pas besoin. Cela a du sens, en fait. Pourtant, il vaut la peine d'envisager d'avoir un XOR avec un point de séquence au milieu. Par exemple, l'expression suivantea un comportement défini et un résultat spécifique en C / C ++ (en ce qui concerne le séquençage au moins). Donc, on peut raisonnablement s’attendre à la même chose de la part du XOR logique défini par l’utilisateur , comme dans
tandis qu'un
!=
XOR basé sur n'a pas cette propriété.la source
||
et&&
: C) , ils évaluent les opérandes dans un contexte booléen. C'est,1 && 2
est vrai, contrairement à1 & 2
ce qui est zéro. De même, un^^
opérateur pourrait être utile pour fournir cette fonctionnalité supplémentaire, d'évaluer les opérandes dans un contexte booléen. Par exemple,1 ^^ 2
c'est faux (contrairement1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, un appel similaireint x = 2; XOR(++x > 1, x < 5);
donnera le mauvais résultat. L'appel devrait avoir des parenthèses supplémentaires, comme dansint x = 2; XOR( (++x > 1), (x < 5) );
, afin de donner le résultat attendu correct.Il existe une autre façon de faire XOR:
Ce qui peut évidemment être démontré pour fonctionner via:
la source
L'opérateur XOR ne peut pas être court-circuité; c'est-à-dire que vous ne pouvez pas prédire le résultat d'une expression XOR simplement en évaluant son opérande de gauche. Il n'y a donc aucune raison de fournir une
^^
version.la source
&&
et&
du tout. Son argument est qu'il n'y a aucune raison de l'introduire^^
. La propriété qui^^
considérerait toute valeur non nulle comme1
n'étant pas vraiment utile, je pense. Ou du moins je ne vois aucune utilité.Un bon code publié a résolu le problème mieux que! A! =! B
Notez que j'ai dû ajouter le BOOL_DETAIL_OPEN / CLOSE pour que cela fonctionne sur MSVC 2010
la source
Utilisez un simple:
la source
Voici comment je pense que vous écrivez une comparaison XOR en C ++:
Preuve
La preuve en est qu'une étude exhaustive des entrées et sorties montre que dans les deux tableaux, pour chaque ensemble d'entrées le résultat est toujours identique dans les deux tableaux.
Par conséquent, la question initiale était de savoir comment écrire:
La réponse serait
Ou si vous le souhaitez, écrivez
la source
(A || B) && !(A && B)
La première partie est A OR B, qui est le OU inclusif; la deuxième partie est, PAS A ET B. Ensemble, vous obtenez A ou B, mais pas à la fois A et B.
Cela fournira le XOR prouvé dans la table de vérité ci-dessous.
la source
J'utilise "xor" (il semble que ce soit un mot-clé; au moins dans Code :: Blocks, il devient gras) tout comme vous pouvez utiliser "et" au lieu de
&&
et "ou" à la place de||
.Oui, c'est au niveau du bit. Désolé.
la source
and
et cexor
sont des macros de bibliothèque standard. Ils ne viennent pas de "quelque part", ils viennent de <iso646.h>. Ces macros sont également en C99 (pas sûr de C89 / 90).xor
représente cependant xor au niveau du bit , tandis queand
est logique et.struct A { compl A() { } };
par exemple définir un destructeur.Cela fonctionne comme défini. Les conditions sont de détecter si vous utilisez Objective-C , qui demande BOOL au lieu de bool (la longueur est différente!)
la source