Come mai C # non ha un XOR
operatore condizionale ?
Esempio:
true xor false = true
true xor true = false
false xor false = false
Come mai C # non ha un XOR
operatore condizionale ?
Esempio:
true xor false = true
true xor true = false
false xor false = false
& | ^
) e agli operatori condizionali ( && ||
). Ma hai ragione (ovviamente), c'è uno XOR logico ...
Risposte:
In C #, gli operatori condizionali eseguono l'operando secondario solo se necessario .
Poiché uno XOR deve per definizione testare entrambi i valori, una versione condizionale sarebbe sciocca.
Esempi :
AND logico: &
- testa ogni volta entrambi i lati.
OR logico: |
- prova entrambi i lati ogni volta.
AND condizionale: &&
- verifica il 2 ° lato solo se il 1 ° lato è vero.
Condizionale OR: ||
- testare il 2 ° lato solo se il 1 ° lato è falso.
La domanda è un po 'datata ma ...
Ecco come dovrebbe funzionare questo operatore:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
Ecco come l'operatore! = Funziona con i tipi bool:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Quindi, come vedi, inesistente ^^
può essere sostituito con esistente!=
!=
avrebbe funzionato per questo.
AND
e OR
ma niente come XOR
. o almeno non ce ne siamo resi conto !=
:) @TheEvilGreebo
C'è l'operatore XOR logico: ^
Documentazione: operatori C # e operatore ^
^
, quando viene utilizzato con operandi booleani, è un operatore booleano. "per gli operandi bool, l'operatore ^ calcola lo stesso risultato dell'operatore di disuguaglianza! =". È inoltre possibile utilizzare operandi interi xo bit per bit con ^
. C # non è C.
A titolo di chiarimento, l'operatore ^ funziona sia con i tipi integrali che con bool.
Vedere l'operatore ^ di MSDN (riferimenti per C #) :
Gli operatori binari ^ sono predefiniti per i tipi integrali e bool. Per i tipi integrali, ^ calcola l'OR esclusivo bit per bit dei suoi operandi. Per gli operandi bool, ^ calcola l'esclusiva logica-or dei suoi operandi; ovvero, il risultato è vero se e solo se esattamente uno dei suoi operandi è vero.
Forse la documentazione è cambiata dal 2011 quando è stata posta questa domanda.
^
e la precede di cinque anni. Dubito che sia cambiato qualcosa.
Come chiesto da Mark L , ecco la versione corretta:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Ecco la tabella della verità:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Riferimento: OR esclusivo
Oh sì, lo fa.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, proprio come un byte). Questo è un comportamento definito al 100% e gestito in modo sicuro. Il CLR non è maltrattato .; La prima volta che ho visto questo comportamento è stato quando utilizzavo Microsoft Pex.
Lo xor condizionale non esiste, ma puoi usarne uno logico perché xor è definito per booleani e tutti i confronti condizionali vengono valutati come booleani.
Quindi puoi dire qualcosa come:
if ( (a == b) ^ (c == d))
{
}
1
. Questo è un fatto poco noto. Puoi finire in una situazione in cui lo xor di due booleani non falsi è ancora non falso! Detto questo, in questo particolare codice l'operatore xor viene applicato solo ai valori in [0,1] in modo che il mio commento non si applichi (completamente).
&
è anche vulnerabile.
&&
come se fosse &
un errore di compilazione.
Sebbene sia presente un operatore xor logico^
, non esiste un operatore xor condizionale . È possibile ottenere uno xor condizionale di due valori A e B utilizzando quanto segue:
A ? (!B) : B
Le parentesi non sono necessarie, ma le ho aggiunte per chiarezza.
Come sottolineato da The Evil Greebo, questo valuta entrambe le espressioni, ma xor non può essere cortocircuitato come and and or .
0101 ^ 0011
ha il valore 0110
.
Non esiste XOR condizionale (cortocircuito). Gli operatori condizionali sono significativi solo quando c'è un modo per dire in modo definitivo il risultato finale guardando solo il primo argomento. XOR (e l'addizione) richiedono sempre due argomenti, quindi non c'è modo di cortocircuitare dopo il primo argomento.
Se sai A = vero, allora (A XOR B) =! B.
Se conosci A = false, allora (A XOR B) = B.
In entrambi i casi, se conosci A ma non B, allora non sai abbastanza per sapere (A XOR B). Devi sempre imparare i valori di A e B per calcolare la risposta. Non esiste letteralmente alcun caso d'uso in cui è possibile risolvere XOR senza entrambi i valori.
Tieni presente che XOR per definizione ha quattro casi:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Ancora una volta, si spera che sia ovvio da quanto sopra che conoscere il primo valore non è mai sufficiente per ottenere la risposta senza conoscere anche il secondo valore. Tuttavia, nella tua domanda, hai omesso il primo caso. Se invece lo volessi
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
allora puoi davvero ottenerlo con un'operazione condizionale di cortocircuito:
A && !B
Ma non è uno XOR.
Questa domanda ha avuto una risposta affettuosa, ma mi sono imbattuto in una situazione diversa. È vero che non è necessario uno XOR condizionale. È anche vero che può essere utilizzato l'operatore ^. Tuttavia, se è necessario testare solo lo stato "true || false" degli operandi, ^ può causare problemi. Per esempio:
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 questo esempio, se sinistra è impostata su 10 (0xa) e destra è impostata su 5 (0x5), viene immesso il ramo "riuscito". Per questo esempio (semplicistico anche se sciocco), ciò comporterebbe un bug poiché non dovresti girare a sinistra E a destra allo stesso tempo. Ciò che ho raccolto dall'interrogante non è che in realtà volesse un condizionale, ma un modo semplice per eseguire il vero / falso sui valori passati a xor.
Una macro potrebbe fare il trucco:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Sentiti libero di prendermi a schiaffi se non sono nel segno: o)
Ho letto la risposta di jimreed di seguito dopo aver pubblicato questo (cattivo Yapdog!) E la sua è in realtà più semplice. Funzionerebbe e non ho assolutamente idea del motivo per cui la sua risposta è stata respinta ...
if
richiede un'espressione booleana, non verrà nemmeno compilato con un int.
!=
funziona come sostituto?