C # neden koşullu XOR
işleci içermez ?
Misal:
true xor false = true
true xor true = false
false xor false = false
C # neden koşullu XOR
işleci içermez ?
Misal:
true xor false = true
true xor true = false
false xor false = false
& | ^
) karşı koşullu operatörlere ( && ||
) atıfta bulunduğunu düşünüyorum . Ama haklısın (elbette), mantıklı bir
Yanıtlar:
C # 'da, koşullu operatörler yalnızca gerekirse ikincil işlenenlerini yürütür .
Bir XOR tanım gereği her iki değeri de test etmesi gerektiğinden , koşullu bir sürüm aptalca olacaktır.
Örnekler :
Mantıksal VE: &
- her seferinde iki tarafı da test eder.
Mantıksal VEYA: |
- her seferinde iki tarafı da test edin.
Koşullu VE: &&
- 1. taraf doğruysa yalnızca 2. tarafı test eder.
Koşullu VEYA: ||
- yalnızca 1. taraf yanlışsa 2. tarafı test edin.
Soru biraz modası geçmiş ama ...
Bu operatör şu şekilde çalışmalıdır:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
! = Operatörü bool türleriyle şu şekilde çalışır:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Gördüğünüz gibi ^^
mevcut olmayan, mevcut olanla değiştirilebilir!=
!=
bunun için işe yarayacağının farkında olmadığım bir şekilde kendimi elimden geçiriyorum .
AND
ve OR
ancak hiçbir şey XOR
. ya da en azından farkına !=
varmadık :) @TheEvilGreebo
Mantıksal XOR operatörü var: ^
Belgeler: C # Operatörleri ve ^ Operatörü
^
, boolean işlenenleri ile kullanıldığında, bir boole operatörü olduğunu açıkça belirtir . "bool işlenenleri için ^ operatörü eşitsizlik operatörü ile aynı sonucu hesaplar! =". Ayrıca bit tabanlı x veya tamsayı işlenenlerini ^
. C # C değildir.
Açıklık getirmek gerekirse, ^ operatörü hem integral türleri hem de bool ile çalışır.
Bkz MSDN en ^ Operatörü (C # Reference) :
İkili ^ operatörleri, integral türleri ve bool için önceden tanımlanmıştır. İntegral türleri için, ^, işlenenlerinin bitsel dışlayıcı-OR'sini hesaplar. Bool işlenenleri için ^ mantıksal dışlayıcıyı veya işlenenlerinin hesaplanır; yani, sonuç, ancak ve ancak işlenenlerinden tam olarak biri doğruysa doğrudur.
Belki de bu soru sorulduğunda belgeler 2011'den beri değişmiştir.
^
beş yıl önce bahseden ve bundan bahseden diğer yanıta bir yorum veya düzenleme olarak daha uygun görünmektedir . Bir şeyin değiştiğinden şüpheliyim.
Mark L'nin sorduğu gibi , İşte doğru sürüm:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
İşte doğruluk tablosu:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Referans: Münhasır VEYA
Oh evet, öyle.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
tıpkı bir bayt gibi yalnızca bir değerdir ). Bu,% 100 tanımlanmış ve güvenli yönetilen bir davranıştır. CLR kabaca hazırlanmamıştır .; Bu davranışı ilk kez Microsoft Pex kullanırken gördüm.
Koşullu xor mevcut değildir, ancak mantıksal olanı kullanabilirsiniz, çünkü xor boole'lar için tanımlanmıştır ve tüm koşullu karşılaştırmalar boolelerle değerlendirilir.
Böylece şöyle bir şey söyleyebilirsiniz:
if ( (a == b) ^ (c == d))
{
}
1
. Bu az bilinen bir gerçektir. İki yanlış olmayan boolean xor değerinin hala yanlış olmadığı bir duruma düşebilirsiniz! Bu belirli kodda söylendiği gibi, xor operatörü yalnızca [0,1] 'deki değerlere uygulanır, böylece yorumum (tam olarak) geçerli değildir.
&
ayrıca savunmasızdır.
&&
gibi derlediler &
.
Bir olsa da mantıksal xor operatörü ^
, hiçbir orada koşullu xor operatörü. Aşağıdakileri kullanarak A ve B değerlerinden oluşan bir koşullu xor elde edebilirsiniz:
A ? (!B) : B
Parenler gerekli değildir, ancak açıklık için onları ekledim.
Evil Greebo tarafından sivri dışarı olarak, bu değerlendirir her iki ifade, ama xor kısa gibi devre edilemez ve ve veya .
0101 ^ 0011
değere sahiptir 0110
.
Koşullu (kısa devre) XOR diye bir şey yoktur. Koşullu operatörler, yalnızca ilk argümana bakarak nihai sonucu kesin olarak söylemenin bir yolu olduğunda anlamlıdır. XOR (ve toplama) her zaman iki argüman gerektirir, bu nedenle ilk argümandan sonra kısa devre yapmanın bir yolu yoktur.
A = doğru olduğunu biliyorsanız, (A XOR B) =! B.
A = yanlış olduğunu biliyorsanız, (A XOR B) = B.
Her iki durumda da, eğer A'yı biliyor ama B'yi bilmiyorsanız, o zaman bilmek için yeterli bilginiz yoktur (A ÖZEL B). Cevabı hesaplamak için her zaman hem A hem de B'nin değerlerini öğrenmelisiniz. XOR'u her iki değer olmadan çözebileceğiniz hiçbir kullanım durumu yoktur.
XOR'un tanım gereği dört durumu olduğunu unutmayın:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Yine, umarım yukarıdakilerden, ilk değeri bilmenin, ikinci değeri de bilmeden yanıtı almak için asla yeterli olmadığı açıktır. Ancak sorunuzda ilk vakayı atladınız. Bunun yerine istersen
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
o zaman bunu kısa devre yapan bir koşullu işlemle elde edebilirsiniz:
A && !B
Ama bu bir XOR değil.
Bu soru etkili bir şekilde yanıtlandı, ancak farklı bir durumla karşılaştım. Koşullu bir XOR'a gerek olmadığı doğrudur. ^ Operatörünün kullanılabileceği de doğrudur. Ancak, işlenenlerin yalnızca "doğru || yanlış" durumunu test etmeniz gerekiyorsa, ^ soruna yol açabilir. Örneğin:
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...
}
}
Bu örnekte, sol 10 (0xa) ve sağ 5 (0x5) olarak ayarlanmışsa, "başarılı" dal girilir. Bu (aptalca olsa da basit) örnek için, aynı anda sola VE sağa dönmemeniz gerektiğinden, bu bir hataya neden olur. Sorguyu soran kişiden öğrendiğim şey, aslında bir koşullu istediği değil, xor'a aktarılan değerler üzerinde doğru / yanlışı gerçekleştirmenin basit bir yoluydu.
Bir makro hile yapabilir:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
İşaretin dışına çıkarsam beni tokatlamaktan çekinmeyin: o)
Bunu gönderdikten sonra (kötü Yapdog!) Jimreed'in cevabını aşağıda okudum ve onunki aslında daha basit. İşe yarardı ve cevabının neden reddedildiğine dair hiçbir fikrim yok ...
if
Boolean ifadesi gerektirir, int ile bile derlenmez.
!=
Yedek olarak nasıl çalışır?