ทำไม C # ถึงไม่มีตัวXOR
ดำเนินการตามเงื่อนไข?
ตัวอย่าง:
true xor false = true
true xor true = false
false xor false = false
ทำไม C # ถึงไม่มีตัวXOR
ดำเนินการตามเงื่อนไข?
ตัวอย่าง:
true xor false = true
true xor true = false
false xor false = false
& | ^
) เทียบกับตัวดำเนินการตามเงื่อนไข ( && ||
) แต่คุณพูดถูก (แน่นอน) มี XOR ตรรกะ ...
คำตอบ:
ใน C # ตัวดำเนินการตามเงื่อนไขจะเรียกใช้ตัวถูกดำเนินการรองหากจำเป็นเท่านั้น
เนื่องจาก XOR ต้องโดยการกำหนดนิยามทดสอบทั้งสองค่าเวอร์ชันที่มีเงื่อนไขจึงเป็นเรื่องงี่เง่า
ตัวอย่าง :
ตรรกะ AND: &
- ทดสอบทั้งสองด้านทุกครั้ง
ตรรกะหรือ: |
- ทดสอบทั้งสองด้านทุกครั้ง
เงื่อนไข AND: &&
- ทดสอบเฉพาะด้านที่ 2 หากด้านที่ 1 เป็นจริง
เงื่อนไขหรือ: ||
- ทดสอบเฉพาะด้านที่ 2 หากด้านที่ 1 เป็นเท็จ
คำถามค่อนข้างล้าสมัย แต่ ...
นี่คือวิธีการทำงานของตัวดำเนินการนี้:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
นี่คือวิธีที่! = ตัวดำเนินการทำงานกับประเภทบูล:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
ดังที่คุณเห็น^^
สามารถแทนที่ด้วยสิ่งที่มีอยู่!=
!=
จะได้ผลสำหรับสิ่งนี้
AND
และแต่ไม่มีอะไรเป็นOR
XOR
หรืออย่างน้อยเราก็ไม่รู้!=
:) @TheEvilGreebo
มีตัวดำเนินการ XOR ตรรกะ: ^
เอกสารประกอบ: C # Operatorsและ^ Operator
^
เมื่อใช้กับบูลีนตัวถูกดำเนินการเป็นตัวดำเนินการบูลีน "สำหรับตัวถูกดำเนินการบูลตัวดำเนินการ ^ จะคำนวณผลลัพธ์เดียวกันกับตัวดำเนินการอสมการ! =" คุณยังสามารถดำเนินการกับจำนวนเต็ม bitwise-xor ด้วย^
. C # ไม่ใช่ C
เช่นเดียวกับการชี้แจงตัวดำเนินการ ^ ทำงานได้กับทั้งประเภทอินทิกรัลและบูล
ดู^ Operator ของ MSDN (อ้างอิง C #) :
ตัวดำเนินการไบนารี ^ ถูกกำหนดไว้ล่วงหน้าสำหรับประเภทอินทิกรัลและบูล สำหรับชนิดอินทิกรัล ^ จะคำนวณ bitwise เอกสิทธิ์ - หรือของตัวถูกดำเนินการ สำหรับตัวถูกดำเนินการบูล ^ คำนวณตรรกะเอกสิทธิ์หรือของตัวถูกดำเนินการ นั่นคือผลลัพธ์จะเป็นจริงก็ต่อเมื่อตัวถูกดำเนินการตัวใดตัวหนึ่งเป็นจริงเท่านั้น
เอกสารอาจมีการเปลี่ยนแปลงตั้งแต่ปี 2011 เมื่อมีการถามคำถามนี้
^
และเกิดขึ้นก่อนหน้านี้ทีละห้าปี ฉันสงสัยว่ามีอะไรเปลี่ยนแปลงไป
ตามที่Mark Lถามนี่คือเวอร์ชันที่ถูกต้อง:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
นี่คือตารางความจริง:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
อ้างอิง: Exclusive OR
อ๋อใช่แล้ว
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
เช่นเดียวกับไบต์) นี่คือพฤติกรรมที่กำหนดและมีการจัดการที่ปลอดภัย 100% CLR ไม่หยาบขึ้น; ครั้งแรกที่ฉันเห็นพฤติกรรมนี้คือเมื่อใช้ Microsoft Pex
ไม่มี xor ตามเงื่อนไข แต่คุณสามารถใช้ตรรกะได้เนื่องจาก xor ถูกกำหนดไว้สำหรับบูลีนและการเปรียบเทียบตามเงื่อนไขทั้งหมดจะประเมินเป็นบูลีน
ดังนั้นคุณสามารถพูดว่า:
if ( (a == b) ^ (c == d))
{
}
1
คุณอาจไม่ได้คิดเกี่ยวกับกรณีที่บูลที่ไม่เป็นเท็จไม่อาจมีจำนวนเต็มตัวแทน นี่เป็นข้อเท็จจริงที่ทราบกันเล็กน้อย คุณสามารถจบลงในสถานการณ์ที่ xor ของสองบูลีนที่ไม่ใช่เท็จยังคงไม่เป็นเท็จ! ที่กล่าวว่าในรหัสเฉพาะนี้ตัวดำเนินการ xor จะถูกนำไปใช้กับค่าใน [0,1] เท่านั้นดังนั้นความคิดเห็นของฉันจึงใช้ไม่ได้ (ทั้งหมด)
&
ยังมีความเสี่ยง
&&
ราวกับว่ามันเป็นการคอมไพล์&
ผิด
แม้ว่าจะมีตัวดำเนินการ xor แบบลอจิคัล^
แต่ก็ไม่มีตัวดำเนินการ xor แบบมีเงื่อนไข คุณสามารถบรรลุ xor ตามเงื่อนไขของสองค่า A และ B โดยใช้สิ่งต่อไปนี้:
A ? (!B) : B
parens ไม่จำเป็น แต่ฉันเพิ่มเพื่อความชัดเจน
ในฐานะที่เป็นออกแหลมโดยความชั่วร้าย Greebo ประเมินนี้ทั้งการแสดงออก แต่ xor ไม่สามารถลัดสั้น ๆ เช่นและและหรือ
0101 ^ 0011
0110
คุณสามารถใช้ได้:
a = b ^ c;
เช่นเดียวกับใน c / c ++
ไม่มีสิ่งที่เรียกว่า XOR แบบมีเงื่อนไข (การลัดวงจร) ตัวดำเนินการตามเงื่อนไขมีความหมายก็ต่อเมื่อมีวิธีที่จะบอกผลลัพธ์สุดท้ายได้อย่างชัดเจนจากการดูเฉพาะอาร์กิวเมนต์แรกเท่านั้น XOR (และการบวก) ต้องการอาร์กิวเมนต์สองตัวเสมอดังนั้นจึงไม่มีทางที่จะลัดวงจรหลังจากอาร์กิวเมนต์แรก
ถ้าคุณรู้ว่า A = true ดังนั้น (A XOR B) =! B
ถ้าคุณรู้ว่า A = false ดังนั้น (A XOR B) = B
ในทั้งสองกรณีถ้าคุณรู้จัก A แต่ไม่ใช่ B แสดงว่าคุณไม่รู้มากพอที่จะรู้ (A XOR B) คุณต้องเรียนรู้ค่าของทั้ง A และ B เสมอเพื่อคำนวณคำตอบ ไม่มีกรณีการใช้งานที่คุณสามารถแก้ปัญหา XOR ได้โดยไม่มีทั้งสองค่า
โปรดทราบว่า XOR ตามคำจำกัดความมีสี่กรณี:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
อีกครั้งหวังว่าจะเห็นได้ชัดจากข้างต้นว่าการรู้ค่าแรกไม่เพียงพอที่จะได้รับคำตอบโดยไม่ต้องรู้ค่าที่สอง อย่างไรก็ตามในคำถามของคุณคุณไม่ใส่กรณีแรก ถ้าคุณต้องการแทน
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
จากนั้นคุณจะได้รับสิ่งนั้นอย่างแน่นอนโดยการดำเนินการตามเงื่อนไขการลัดวงจร:
A && !B
แต่นั่นไม่ใช่ XOR
คำถามนี้ได้รับคำตอบอย่างมีเหตุผล แต่ฉันเจอสถานการณ์ที่แตกต่างออกไป เป็นความจริงที่ว่าไม่จำเป็นต้องมี XOR แบบมีเงื่อนไข นอกจากนี้ยังสามารถใช้ตัวดำเนินการ ^ ได้ อย่างไรก็ตามหากคุณต้องการทดสอบสถานะ "true || false" ของตัวถูกดำเนินการ ^ อาจทำให้เกิดปัญหาได้ ตัวอย่างเช่น:
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...
}
}
ในตัวอย่างนี้หากตั้งค่าทางซ้ายเป็น 10 (0xa) และตั้งค่าทางขวาเป็น 5 (0x5) สาขา "ความสำเร็จ" จะถูกป้อน สำหรับตัวอย่างนี้ (ง่ายถ้าโง่) สิ่งนี้จะทำให้เกิดข้อผิดพลาดเนื่องจากคุณไม่ควรเลี้ยวซ้ายและขวาพร้อมกัน สิ่งที่ฉันรวบรวมจากผู้ถามไม่ใช่ว่าเขาต้องการเงื่อนไข แต่เป็นวิธีง่ายๆในการดำเนินการจริง / เท็จกับค่าที่ส่งไปยัง xor
มาโครสามารถทำเคล็ดลับ:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
อย่าลังเลที่จะตบฉันถ้าฉันไม่ได้ทำเครื่องหมาย: o)
ฉันอ่านคำตอบของ jimreed ด้านล่างหลังจากที่ฉันโพสต์สิ่งนี้ (Yapdog ไม่ดี!) และมันก็ง่ายกว่าจริงๆ มันจะได้ผลและฉันไม่รู้เลยว่าทำไมคำตอบของเขาถึงถูกโหวตลง ...
if
ต้องการนิพจน์บูลีนมันจะไม่รวบรวมด้วย int
!=
ทำงานแทน?