Czy jest coś takiego? Po raz pierwszy spotkałem się z praktyczną potrzebą, ale nie widzę takiej w Stroustrup . Zamierzam napisać:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Ale nie ma ^^
operatora. Czy mogę użyć bitowej ^
tutaj i uzyskać prawidłową odpowiedź (niezależnie od reprezentacji maszynowej prawdy i fałszu)? Nigdy nie mieszam &
i &&
, lub, |
i ||
dlatego waham się czynić to z ^
i ^^
.
bool XOR(bool,bool)
Zamiast tego wygodniej byłoby napisać własną funkcję.
Odpowiedzi:
!=
Operatora tego celu służy dobool
wartości.źródło
bool
wartościach”, ponieważ niekoniecznie robi to, co możesz chcieć dla nie-booleanów. A ponieważ jest to C ++, istnieje prawdziwybool
typ zamiast konieczności używaniaint
do tego celu.a
prostu napisz!(a) != !(a)
W przypadku prawdziwej logicznej operacji XOR będzie to działać:
Zauważ, że
!
są tam, aby przekonwertować wartości na wartości logiczne i zanegować je, aby dwie nierówne dodatnie liczby całkowite (każda atrue
) byłyby ocenionefalse
.źródło
!!
działałoby po prostu dobrze zapytać, ale ponieważ muszą być inni, negowanie ich nie szkodzi.Prawidłowa ręczna logiczna implementacja XOR zależy od tego, jak ściśle chcesz naśladować ogólne zachowanie innych operatorów logicznych (
||
i&&
) z twoim XOR. Są dwie ważne rzeczy na temat tych operatorów: 1) gwarantują ocenę zwarcia, 2) wprowadzają punkt sekwencyjny, 3) oceniają operandy tylko raz.Jak można zrozumieć, oceny XOR nie można zwierać, ponieważ wynik zawsze zależy od obu argumentów. Więc 1 nie wchodzi w rachubę. Ale co z 2? Jeśli nie przejmujesz się 2, to przy znormalizowanych (tj.
bool
) Wartościach operator!=
wykonuje zadanie XOR pod względem wyniku. W razie potrzeby operandy można łatwo znormalizować za pomocą unary!
. W ten sposób!A != !B
implementuje prawidłowy XOR w tym zakresie.Ale jeśli zależy ci na dodatkowym punkcie sekwencyjnym, ani
!=
ani bitowe nie^
jest właściwym sposobem na wdrożenie XOR. Jeden z możliwych sposobów prawidłowego wykonania XOR (a, b) może wyglądać następującoJest to tak blisko, jak to tylko możliwe, aby domowej roboty XOR były „podobne” do
||
i&&
. Działa to oczywiście tylko wtedy, gdy zaimplementujesz swój XOR jako makro. Funkcja nie zadziała, ponieważ sekwencjonowanie nie będzie miało zastosowania do argumentów funkcji.Ktoś może jednak powiedzieć, że jedynym powodem mający temperaturę w każdej sekwencji
&&
i||
jest wspieranie oceny zwarcia, a tym samym XOR nie potrzebuje. To ma sens. Warto jednak wziąć pod uwagę XOR z punktem sekwencyjnym pośrodku. Na przykład następujące wyrażeniema zdefiniowane zachowanie i określony wynik w C / C ++ (przynajmniej w odniesieniu do sekwencjonowania). Można więc zasadnie oczekiwać tego samego od logicznego XOR zdefiniowanego przez użytkownika , jak w
podczas gdy
!=
oparty na XOR nie ma tej właściwości.źródło
||
i&&
: C) oceniają argumentów w kontekście logicznym. To jest1 && 2
prawda, w przeciwieństwie do tego,1 & 2
która wynosi zero. Podobnie,^^
operator może być przydatny do zapewnienia tej dodatkowej funkcji, oceny operandów w kontekście logicznym. Np.1 ^^ 2
Jest fałszywe (w przeciwieństwie do1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, to wywołanie podobneint x = 2; XOR(++x > 1, x < 5);
da zły wynik. Wezwanie musiałoby zawierać dodatkowe nawiasy, np. Wint x = 2; XOR( (++x > 1), (x < 5) );
, aby zapewnić poprawny oczekiwany wynik.Istnieje inny sposób wykonania XOR:
Które oczywiście można wykazać poprzez:
źródło
Operatora XOR nie można zwierać; tzn. nie można przewidzieć wyniku wyrażenia XOR jedynie poprzez ocenę jego operandu po lewej stronie. Dlatego nie ma powodu, aby podawać
^^
wersję.źródło
&&
i&
w ogóle. Chodzi o to, że nie ma powodu do wprowadzania^^
. Podejrzewam, że właściwość, która^^
uznałaby każdą wartość inną niż null za1
mało użyteczną. A przynajmniej nie widzę żadnego zastosowania.Napisano dobry kod, który rozwiązał problem lepiej niż! A! =! B
Pamiętaj, że musiałem dodać BOOL_DETAIL_OPEN / CLOSE, aby działało na MSVC 2010
źródło
Użyj prostego:
źródło
Oto jak myślę, że piszesz porównanie XOR w C ++:
Dowód
Dowód jest taki, że wyczerpujące badanie danych wejściowych i wyjściowych pokazuje, że w dwóch tabelach dla każdego zestawu danych wejściowych wynik jest zawsze identyczny w dwóch tabelach.
Dlatego pierwotne pytanie brzmi: jak pisać:
Odpowiedź brzmi:
Lub jeśli chcesz, napisz
źródło
(A || B) && !(A && B)
Pierwsza część to A OR B, która jest Inclusive OR; druga część to NIE A i B. Razem dostajesz A lub B, ale nie oba A i B.
Zapewni to XOR udowodnione w poniższej tabeli prawdy.
źródło
Używam „xor” (wygląda na to, że jest słowem kluczowym; przynajmniej w Code :: Blocks robi się pogrubionym), tak jak możesz używać „i” zamiast
&&
i „lub” zamiast||
.Tak, to jest bitowe. Przepraszam.
źródło
and
ixor
to standardowe makra biblioteczne. Nie pochodzą z „gdzieś”, pochodzą z <iso646.h>. Te makra są również w C99 (nie jestem pewien co do C89 / 90).xor
oznacza jednak bitowe xor, podczas gdyand
jest logiczne i.struct A { compl A() { } };
na przykład zdefiniować destruktor.Działa zgodnie z definicją. Warunkami są wykrywanie, czy używasz Objective-C , który prosi o BOOL zamiast bool (długość jest inna!)
źródło