Dlaczego C # nie ma XOR
operatora warunkowego ?
Przykład:
true xor false = true
true xor true = false
false xor false = false
Dlaczego C # nie ma XOR
operatora warunkowego ?
Przykład:
true xor false = true
true xor true = false
false xor false = false
& | ^
) kontra operatory warunkowe ( && ||
). Ale masz rację (oczywiście), istnieje logiczna XOR ...
Odpowiedzi:
W języku C # operatory warunkowe wykonują swój pomocniczy operand tylko w razie potrzeby .
Ponieważ XOR musi z definicji testować obie wartości, wersja warunkowa byłaby głupia.
Przykłady :
Logiczne AND: &
- testuje za każdym razem obie strony.
Logiczne LUB: |
- za każdym razem testuj obie strony.
I warunkowe: &&
- testuje drugą stronę tylko wtedy, gdy pierwsza jest prawdziwa.
Warunkowe LUB: ||
- testuj drugą stronę tylko wtedy, gdy pierwsza strona jest fałszywa.
Pytanie jest nieco przestarzałe, ale ...
Tak powinien działać ten operator:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
Oto jak! = Operator działa z typami bool:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Więc jak widzisz, nieistniejący ^^
może zostać zastąpiony istniejącym!=
!=
że to zadziała.
AND
i OR
ale nic jak XOR
. a przynajmniej nie zdawaliśmy sobie sprawy !=
:) @TheEvilGreebo
Istnieje logiczny operator XOR: ^
Dokumentacja: Operatory C # i ^ Operator
^
w przypadku użycia z operandami boolowskimi jest operatorem boolowskim. "dla operandów bool, operator ^ oblicza ten sam wynik, co operator nierówności! =". Możesz także bitwise-xor integer operandy z ^
. C # nie jest C.
Dla wyjaśnienia, operator ^ działa zarówno z typami całkowitymi, jak i logicznymi.
Zobacz ^ Operator MSDN (odwołanie w C #) :
Operatory binarne ^ są wstępnie zdefiniowane dla typów całkowitych i bool. W przypadku typów całkowitych ^ oblicza bitowy OR na wyłączność swoich operandów. Dla operandów bool, ^ oblicza logiczne wyłączne-lub swoich operandów; to znaczy, wynik jest prawdziwy wtedy i tylko wtedy, gdy dokładnie jeden z jego argumentów jest prawdziwy.
Być może dokumentacja zmieniła się od 2011 roku, kiedy zadano to pytanie.
^
i jest o pięć lat wcześniejsza. Wątpię, żeby coś się zmieniło.
Zgodnie z zapytaniem Marka L. Oto poprawna wersja:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Oto tabela prawdy:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Odniesienie: ekskluzywny OR
O tak, to prawda.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, tak jak bajt). Jest to w 100% zdefiniowane i bezpieczne zarządzane zachowanie. CLR nie jest nierówny .; Po raz pierwszy zobaczyłem to zachowanie podczas korzystania z Microsoft Pex.
Warunkowe xor nie istnieje, ale możesz użyć logicznego, ponieważ xor jest zdefiniowany dla wartości logicznych, a wszystkie porównania warunkowe są obliczane na wartości logiczne.
Możesz więc powiedzieć coś takiego:
if ( (a == b) ^ (c == d))
{
}
1
. To mało znany fakt. Możesz skończyć w sytuacji, w której xor dwóch niefałszowanych wartości logicznych nadal nie jest fałszywy! To powiedziawszy w tym konkretnym kodzie, operator xor jest zawsze stosowany tylko do wartości w [0,1], więc mój komentarz nie ma (w pełni) zastosowania.
&
jest również wrażliwy.
&&
tak, jakby to była &
błędna kompilacja.
Chociaż istnieje logiczny operator xor ^
, nie ma warunkowego operatora xor. Możesz uzyskać warunkowy xor dwóch wartości A i B za pomocą:
A ? (!B) : B
Pareny nie są konieczne, ale dodałem je dla jasności.
Jak wskazał The Evil Greebo, oblicza to oba wyrażenia, ale xor nie może być zwarty jak i i lub .
0101 ^ 0011
ma wartość 0110
.
Nie ma czegoś takiego jak warunkowy (zwierający) XOR. Operatory warunkowe mają znaczenie tylko wtedy, gdy istnieje sposób na ostateczne określenie wyniku końcowego, patrząc tylko na pierwszy argument. XOR (i dodawanie) zawsze wymaga dwóch argumentów, więc nie ma możliwości zwarcia po pierwszym argumencie.
Jeśli wiesz, że A = prawda, to (A XOR B) =! B.
Jeśli wiesz, że A = fałsz, to (A XOR B) = B.
W obu przypadkach, jeśli znasz A, ale nie znasz B, to nie wiesz wystarczająco dużo, aby wiedzieć (A XOR B). Aby obliczyć odpowiedź, zawsze musisz poznać wartości A i B. Nie ma dosłownie żadnego przypadku użycia, w którym można by kiedykolwiek rozwiązać XOR bez obu wartości.
Pamiętaj, że XOR z definicji ma cztery przypadki:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Miejmy nadzieję, że z powyższego jasno wynika, że znajomość pierwszej wartości nigdy nie wystarczy, aby uzyskać odpowiedź bez znajomości drugiej wartości. Jednak w swoim pytaniu pominąłeś pierwszy przypadek. Jeśli zamiast tego chciałeś
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
wtedy rzeczywiście możesz to uzyskać poprzez zwieranie operacji warunkowej:
A && !B
Ale to nie jest XOR.
Na to pytanie udzielono pozytywnej odpowiedzi, ale trafiłem na inną sytuację. Prawdą jest, że nie ma potrzeby warunkowego XOR. Prawdą jest również, że można użyć operatora ^. Jeśli jednak potrzebujesz tylko przetestować stan argumentów „prawda || fałsz”, wtedy ^ może spowodować problemy. Na przykład:
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...
}
}
W tym przykładzie, jeśli left jest ustawione na 10 (0xa), a prawe jest ustawione na 5 (0x5), wprowadzana jest gałąź „Success”. W tym (prostym, choć głupim) przykładzie spowodowałoby to błąd, ponieważ nie należy jednocześnie skręcać w lewo ORAZ w prawo. To, co otrzymałem od pytającego, to nie to, że faktycznie chciał warunkowej, ale prosty sposób na wykonanie prawdy / fałszu na wartościach przekazanych do xor.
Makro może załatwić sprawę:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Możesz mnie spoliczkować, jeśli nie mam racji: o)
Przeczytałem odpowiedź jimreeda poniżej po tym, jak to opublikowałem (zły Yapdog!), A jego jest właściwie prostszy. To by zadziałało i absolutnie nie mam pojęcia, dlaczego jego odpowiedź została odrzucona ...
if
wymaga wyrażenia logicznego, nie zostanie nawet skompilowany z wartością typu int.
!=
działa jako substytut?