Wie kommt es, dass C # keinen bedingten XOR
Operator hat?
Beispiel:
true xor false = true
true xor true = false
false xor false = false
Wie kommt es, dass C # keinen bedingten XOR
Operator hat?
Beispiel:
true xor false = true
true xor true = false
false xor false = false
& | ^
) und bedingte Operatoren ( && ||
). Aber Sie haben Recht (natürlich), es gibt eine logische XOR ...
Antworten:
In C # führen bedingte Operatoren ihren sekundären Operanden nur bei Bedarf aus .
Da ein XOR per Definition beide Werte testen muss , wäre eine bedingte Version dumm.
Beispiele :
Logisches UND: &
- testet jedes Mal beide Seiten.
Logisches ODER: |
- Testen Sie jedes Mal beide Seiten.
Bedingtes UND: &&
- testet die 2. Seite nur, wenn die 1. Seite wahr ist.
Bedingtes ODER: ||
- Testen Sie die 2. Seite nur, wenn die 1. Seite falsch ist.
Frage ist etwas veraltet, aber ...
So sollte dieser Operator funktionieren:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
So funktioniert der Operator! = Mit Bool-Typen:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Wie Sie sehen, ^^
kann nicht vorhandenes durch vorhandenes ersetzt werden!=
!=
das funktionieren würde.
AND
und OR
doch nichts als XOR
. oder zumindest haben wir nicht realisiert !=
:) @TheEvilGreebo
Es gibt den logischen XOR-Operator: ^
Dokumentation: C # -Operatoren und ^ Operator
^
sich bei Verwendung mit booleschen Operanden um einen booleschen Operator handelt. "Für die Bool-Operanden berechnet der Operator ^ das gleiche Ergebnis wie der Ungleichungsoperator! =". Sie können auch bitweise x oder ganzzahlige Operanden mit verwenden ^
. C # ist nicht C.
Zur Verdeutlichung arbeitet der Operator ^ sowohl mit integralen Typen als auch mit bool.
Siehe ^ Operator ^ von MSDN (C # -Referenz) :
Binäre ^ Operatoren sind für die Integraltypen und bool vordefiniert. Für integrale Typen berechnet ^ das bitweise Exklusiv-ODER seiner Operanden. Für Bool-Operanden berechnet ^ das logische Exklusiv-Oder seiner Operanden. Das Ergebnis ist genau dann wahr, wenn genau einer seiner Operanden wahr ist.
Möglicherweise hat sich die Dokumentation seit 2011 geändert, als diese Frage gestellt wurde.
^
die diese erwähnt und um fünf Jahre älter ist, angemessener zu sein . Ich bezweifle, dass sich etwas geändert hat.
Wie von Mark L gefragt , ist hier die richtige Version:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Hier ist die Wahrheitstabelle:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Referenz: Exklusiv ODER
Oh ja, das tut es.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, genau wie ein Byte). Dies ist ein zu 100% definiertes und sicher verwaltetes Verhalten. Die CLR ist nicht aufgeraut.; Das erste Mal, dass ich dieses Verhalten sah, war bei Verwendung von Microsoft Pex.
Bedingtes xor existiert nicht, aber Sie können logisches verwenden, da xor für Boolesche Werte definiert ist und alle bedingten Vergleiche zu Booleschen Werten ausgewertet werden.
Sie können also etwas sagen wie:
if ( (a == b) ^ (c == d))
{
}
1
. Dies ist eine wenig bekannte Tatsache. Sie können in eine Situation geraten, in der das xor von zwei nicht falschen Booleschen Werten immer noch nicht falsch ist! Das heißt, in diesem speziellen Code wird der xor-Operator immer nur auf Werte in [0,1] angewendet, so dass mein Kommentar nicht (vollständig) gilt.
&
ist auch anfällig.
&&
als wäre es &
eine Fehlkompilierung.
Während es einen logischen xor-Operator ^
gibt, gibt es keinen bedingten xor-Operator. Sie können ein bedingtes xor von zwei Werten A und B erreichen, indem Sie Folgendes verwenden:
A ? (!B) : B
Die Parens sind nicht notwendig, aber ich habe sie der Klarheit halber hinzugefügt.
Wie The Evil Greebo hervorhebt, bewertet dies beide Ausdrücke, aber xor kann nicht wie und und oder kurzgeschlossen werden .
0101 ^ 0011
hat den Wert 0110
.
Bedingtes (kurzgeschlossenes) XOR gibt es nicht. Bedingte Operatoren sind nur dann sinnvoll, wenn es eine Möglichkeit gibt, das Endergebnis endgültig zu bestimmen, wenn nur das erste Argument betrachtet wird. XOR (und Addition) erfordern immer zwei Argumente, sodass nach dem ersten Argument kein Kurzschluss möglich ist.
Wenn Sie A = wahr kennen, dann ist (A XOR B) =! B.
Wenn Sie A = falsch kennen, dann ist (A XOR B) = B.
In beiden Fällen, wenn Sie A kennen, aber nicht B, dann wissen Sie nicht genug, um es zu wissen (A XOR B). Sie müssen immer die Werte von A und B lernen, um die Antwort zu berechnen. Es gibt buchstäblich keinen Anwendungsfall, in dem Sie das XOR jemals ohne beide Werte auflösen können.
Beachten Sie, dass XOR per Definition vier Fälle hat:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Wiederum ist aus den obigen Ausführungen hoffentlich ersichtlich, dass die Kenntnis des ersten Werts niemals ausreicht, um die Antwort zu erhalten, ohne auch den zweiten Wert zu kennen. In Ihrer Frage haben Sie jedoch den ersten Fall weggelassen. Wenn du stattdessen wolltest
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
dann können Sie das tatsächlich durch eine kurzschließende bedingte Operation erhalten:
A && !B
Aber das ist kein XOR.
Diese Frage wurde affektiv beantwortet, aber ich bin auf eine andere Situation gestoßen. Es ist wahr, dass keine bedingte XOR erforderlich ist. Es ist auch wahr, dass der Operator ^ verwendet werden kann. Wenn Sie jedoch nur den Status "true || false" der Operanden testen müssen, kann ^ zu Problemen führen. Beispielsweise:
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...
}
}
In diesem Beispiel wird der Zweig "Erfolg" eingegeben, wenn links auf 10 (0xa) und rechts auf 5 (0x5) gesetzt ist. In diesem (simplen, wenn auch albernen) Beispiel würde dies zu einem Fehler führen, da Sie nicht gleichzeitig nach links und rechts abbiegen sollten. Was ich vom Fragesteller erfahren habe, ist nicht, dass er tatsächlich eine Bedingung wollte, sondern eine einfache Möglichkeit, das Wahr / Falsch für die an xor übergebenen Werte auszuführen.
Ein Makro könnte den Trick machen:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Fühlen Sie sich frei, mich herumzuschlagen, wenn ich daneben bin: o)
Ich habe Jimreeds Antwort unten gelesen, nachdem ich dies gepostet habe (schlechter Yapdog!) Und seine ist tatsächlich einfacher. Es würde funktionieren und ich habe absolut keine Ahnung, warum seine Antwort abgelehnt wurde ...
if
erfordert einen booleschen Ausdruck, der nicht einmal mit einem int kompiliert werden kann.
!=
arbeitet man als Ersatz?