Comment se fait-il que C # n'ait pas d' XOR
opérateur conditionnel ?
Exemple:
true xor false = true
true xor true = false
false xor false = false
Comment se fait-il que C # n'ait pas d' XOR
opérateur conditionnel ?
Exemple:
true xor false = true
true xor true = false
false xor false = false
& | ^
) vs opérateurs conditionnels ( && ||
). Mais vous avez raison (bien sûr), il y a un XOR logique ...
Réponses:
En C #, les opérateurs conditionnels n'exécutent leur opérande secondaire que si nécessaire .
Puisqu'un XOR doit par définition tester les deux valeurs, une version conditionnelle serait idiote.
Exemples :
ET logique: &
- teste les deux côtés à chaque fois.
OU logique: |
- testez les deux côtés à chaque fois.
ET conditionnel: &&
- ne teste le 2ème côté que si le 1er côté est vrai.
OR conditionnel: ||
- tester uniquement le 2ème côté si le 1er côté est faux.
La question est un peu dépassée mais ...
C'est ainsi que doit fonctionner cet opérateur:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
Voici comment l'opérateur! = Fonctionne avec les types booléens:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Ainsi, comme vous le voyez, inexistante ^^
peut être remplacée par une!=
!=
cela fonctionnerait.
AND
et OR
mais rien de plus XOR
. ou du moins nous n'avons pas réalisé !=
:) @TheEvilGreebo
Il y a l'opérateur logique XOR: ^
Documentation: opérateurs C # et opérateur ^
^
, lorsqu'il est utilisé avec des opérandes booléens, est un opérateur booléen. "pour les opérandes booléens, l'opérateur ^ calcule le même résultat que l'opérateur d'inégalité! =". Vous pouvez également utiliser des opérandes entiers xor bit à bit avec ^
. C # n'est pas C.
Pour clarifier, l'opérateur ^ fonctionne avec les types intégraux et booléens.
Voir l'opérateur ^ de MSDN (référence C #) :
Les opérateurs binaires ^ sont prédéfinis pour les types intégraux et booléens. Pour les types intégraux, ^ calcule le OU exclusif au niveau du bit de ses opérandes. Pour les opérandes booléens, ^ calcule le ou exclusif logique de ses opérandes; autrement dit, le résultat est vrai si et seulement si exactement l'un de ses opérandes est vrai.
Peut-être que la documentation a changé depuis 2011 lorsque cette question a été posée.
^
et précède celle-ci de cinq ans. Je doute que quelque chose ait changé.
Comme demandé par Mark L , voici la version correcte:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Voici la table de vérité:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Référence: OU exclusif
Oh oui, c'est vrai.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, tout comme un octet). Il s'agit d'un comportement défini et géré à 100%. Le CLR n'est pas grossier .; La première fois que j'ai vu ce comportement, c'était lors de l'utilisation de Microsoft Pex.
Le xor conditionnel n'existe pas, mais vous pouvez en utiliser un logique car xor est défini pour les booléens et toutes les comparaisons conditionnelles sont évaluées en booléens.
Vous pouvez donc dire quelque chose comme:
if ( (a == b) ^ (c == d))
{
}
1
. C'est un fait peu connu. Vous pouvez vous retrouver dans une situation où le xor de deux booléens non faux est toujours non faux! Cela dit dans ce code particulier, l'opérateur xor n'est jamais appliqué qu'aux valeurs de [0,1] afin que mon commentaire ne s'applique pas (entièrement).
&
est également vulnérable.
&&
comme si c'était &
une mauvaise compilation.
Bien qu'il existe un opérateur xor logique^
, il n'y a pas d' opérateur xor conditionnel . Vous pouvez obtenir un xor conditionnel de deux valeurs A et B en utilisant ce qui suit:
A ? (!B) : B
Les parens ne sont pas nécessaires, mais je les ai ajoutés pour plus de clarté.
Comme l'a souligné The Evil Greebo, cela évalue les deux expressions, mais xor ne peut pas être court-circuité comme et et ou .
0101 ^ 0011
a la valeur 0110
.
Il n'existe pas de XOR conditionnel (court-circuit). Les opérateurs conditionnels n'ont de sens que lorsqu'il existe un moyen de déterminer définitivement le résultat final en ne regardant que le premier argument. XOR (et l'addition) nécessitent toujours deux arguments, il n'y a donc aucun moyen de court-circuiter après le premier argument.
Si vous connaissez A = vrai, alors (A XOR B) =! B.
Si vous connaissez A = faux, alors (A XOR B) = B.
Dans les deux cas, si vous connaissez A mais pas B, alors vous n'en savez pas assez pour savoir (A XOR B). Vous devez toujours apprendre les valeurs de A et de B pour calculer la réponse. Il n'y a littéralement aucun cas d'utilisation où vous pouvez résoudre le XOR sans les deux valeurs.
Gardez à l'esprit que XOR a par définition quatre cas:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Encore une fois, j'espère qu'il est évident d'après ce qui précède que connaître la première valeur n'est jamais suffisant pour obtenir la réponse sans connaître également la deuxième valeur. Cependant, dans votre question, vous avez omis le premier cas. Si tu voulais plutôt
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
alors vous pouvez en effet l'obtenir par une opération conditionnelle de court-circuit:
A && !B
Mais ce n'est pas un XOR.
Cette question a reçu une réponse affective, mais je suis tombé sur une situation différente. Il est vrai qu'il n'y a pas besoin d'un XOR conditionnel. Il est également vrai que l'opérateur ^ peut être utilisé. Cependant, si vous avez seulement besoin de tester le statut "true || false" des opérandes, alors ^ peut entraîner des problèmes. Par exemple:
void Turn(int left, int right)
{
if (left ^ right)
{
//success... turn the car left or right...
}
else
{
//error... no turn or both left AND right are set...
}
}
Dans cet exemple, si la gauche est définie sur 10 (0xa) et la droite sur 5 (0x5), la branche «succès» est entrée. Pour cet exemple (simpliste si idiot), cela entraînerait un bogue puisque vous ne devriez pas tourner à gauche ET à droite en même temps. Ce que j'ai compris du questionneur n'est pas qu'il voulait en fait un conditionnel, mais un moyen simple d'effectuer le vrai / faux sur les valeurs transmises au xor.
Une macro pourrait faire l'affaire:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
N'hésitez pas à me gifler si je suis hors de propos: o)
J'ai lu la réponse de Jimreed ci-dessous après avoir posté ceci (mauvais Yapdog!) Et la sienne est en fait plus simple. Cela fonctionnerait et je n'ai absolument aucune idée de la raison pour laquelle sa réponse a été rejetée ...
if
nécessite une expression booléenne, il ne se compilera même pas avec un int.
!=
fonctionne comme substitut?