Tại sao C # không có XOR
toán tử điều kiện ?
Thí dụ:
true xor false = true
true xor true = false
false xor false = false
Tại sao C # không có XOR
toán tử điều kiện ?
Thí dụ:
true xor false = true
true xor true = false
false xor false = false
& | ^
) so với toán tử điều kiện ( && ||
). Nhưng bạn đúng (tất nhiên), có một XOR hợp lý ...
Câu trả lời:
Trong C #, các toán tử có điều kiện chỉ thực hiện toán hạng phụ của chúng nếu cần thiết .
Vì một XOR theo định nghĩa phải kiểm tra cả hai giá trị, một phiên bản có điều kiện sẽ là ngớ ngẩn.
Ví dụ :
Logic AND: &
- kiểm tra cả hai mặt mọi lúc.
Hợp lý HOẶC: |
- kiểm tra cả hai mặt mọi lúc.
AND có điều kiện: &&
- chỉ kiểm tra vế thứ 2 nếu vế thứ nhất là đúng.
HOẶC có điều kiện: ||
- chỉ kiểm tra mặt thứ 2 nếu mặt thứ nhất là sai.
Câu hỏi hơi lỗi thời nhưng ...
Đó là cách toán tử này hoạt động:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
Đây là cách toán tử! = Hoạt động với các kiểu bool:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Vì vậy, như bạn thấy ^^
không tồn tại có thể được thay thế bằng!=
!=
sẽ làm việc cho điều này.
AND
và OR
nhưng không có gì như XOR
. hoặc ít nhất là chúng tôi đã không nhận ra !=
:) @TheEvilGreebo
Có toán tử XOR logic: ^
Tài liệu: Các toán tử C # và ^ Toán tử
^
, khi được sử dụng với toán hạng boolean, là một toán tử boolean. "đối với toán hạng bool, toán tử ^ tính kết quả giống như toán tử bất đẳng thức! =". Bạn cũng có thể sử dụng toán hạng số nguyên bitwise-xor ^
. C # không phải là C.
Để làm rõ, toán tử ^ hoạt động với cả hai loại tích phân và bool.
Xem MSDN's ^ Operator (C # Reference) :
Toán tử ^ nhị phân được xác định trước cho các kiểu tích phân và bool. Đối với các kiểu tích phân, ^ tính toán OR riêng-OR của các toán hạng của nó. Đối với toán hạng bool, ^ tính toán loại trừ logic-hoặc của các toán hạng của nó; nghĩa là, kết quả là true nếu và chỉ khi chính xác một trong các toán hạng của nó là true.
Có thể tài liệu đã thay đổi kể từ năm 2011 khi câu hỏi này được hỏi.
^
và có trước câu trả lời này khoảng 5 năm. Tôi nghi ngờ bất cứ điều gì đã thay đổi.
Theo yêu cầu của Mark L , Đây là phiên bản chính xác:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Đây là bảng sự thật:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Tham khảo: Độc quyền HOẶC
Ồ vâng, đúng rồi.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, giống như một byte vậy). Đây là hành vi được quản lý an toàn và được xác định 100%. CLR không phải là hoàn thiện; Lần đầu tiên tôi thấy hành vi này là khi sử dụng Microsoft Pex.
Xor có điều kiện không tồn tại, nhưng bạn có thể sử dụng logic vì xor được định nghĩa cho boolean và tất cả các phép so sánh có điều kiện đều đánh giá thành boolean.
Vì vậy, bạn có thể nói điều gì đó như:
if ( (a == b) ^ (c == d))
{
}
1
. Đây là một thực tế ít được biết đến. Bạn có thể kết thúc trong một tình huống mà xor của hai boolean không sai vẫn không sai! Điều đó nói trong mã cụ thể này, toán tử xor chỉ được áp dụng cho các giá trị trong [0,1] để nhận xét của tôi không áp dụng (hoàn toàn).
&
cũng dễ bị tổn thương.
&&
như thể &
đó là một biên dịch sai.
Trong khi có toán tử xor logic^
, không có toán tử xor có điều kiện . Bạn có thể đạt được điều kiện xor của hai giá trị A và B bằng cách sử dụng như sau:
A ? (!B) : B
Các parens không cần thiết, nhưng tôi đã thêm chúng để rõ ràng.
Như đã chỉ ra bởi The Evil Greebo, điều này đánh giá cả hai biểu thức, nhưng xor không thể bị đoản mạch như và và hoặc .
0101 ^ 0011
có giá trị 0110
.
Không có cái gọi là XOR có điều kiện (đoản mạch). Các toán tử điều kiện chỉ có ý nghĩa khi có một cách để nói rõ ràng kết quả cuối cùng từ việc chỉ xem xét đối số đầu tiên. XOR (và phép cộng) luôn yêu cầu hai đối số, vì vậy không có cách nào để đoản mạch sau đối số đầu tiên.
Nếu bạn biết A = true, thì (A XOR B) =! B.
Nếu bạn biết A = false, thì (A XOR B) = B.
Trong cả hai trường hợp, nếu bạn biết A nhưng không biết B, thì bạn không biết đủ để biết (A XOR B). Bạn phải luôn học giá trị của cả A và B để tính toán câu trả lời. Thực sự không có trường hợp sử dụng nào mà bạn có thể giải quyết XOR mà không có cả hai giá trị.
Hãy nhớ rằng, XOR theo định nghĩa có bốn trường hợp:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Một lần nữa, hy vọng điều hiển nhiên ở trên rằng biết giá trị đầu tiên không bao giờ là đủ để có câu trả lời mà không cần biết giá trị thứ hai. Tuy nhiên, trong câu hỏi của bạn, bạn đã bỏ qua trường hợp đầu tiên. Thay vào đó nếu bạn muốn
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
thì bạn thực sự có thể đạt được điều đó bằng một hoạt động có điều kiện đoản mạch:
A && !B
Nhưng đó không phải là XOR.
Câu hỏi này đã được trả lời một cách khách quan, nhưng tôi đã gặp phải một tình huống khác. Đúng là không cần XOR có điều kiện. Cũng đúng khi toán tử ^ có thể được sử dụng. Tuy nhiên, nếu bạn chỉ cần kiểm tra trạng thái "true || false" của các toán hạng thì ^ có thể dẫn đến rắc rối. Ví dụ:
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...
}
}
Trong ví dụ này, nếu trái được đặt thành 10 (0xa) và phải được đặt thành 5 (0x5) thì nhánh "thành công" được nhập. Đối với ví dụ này (đơn giản nếu ngớ ngẩn), điều này sẽ dẫn đến lỗi vì bạn không nên rẽ trái VÀ phải cùng một lúc. Những gì tôi thu thập được từ người hỏi không phải là anh ta thực sự muốn có một điều kiện, mà là một cách đơn giản để thực hiện đúng / sai trên các giá trị được chuyển đến xor.
Một macro có thể thực hiện thủ thuật:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Cứ thoải mái tát tôi nếu tôi đi chệch hướng: o)
Tôi đọc câu trả lời của jimreed bên dưới sau khi tôi đăng bài này (Yapdog xấu!) Và của anh ấy thực sự đơn giản hơn. Nó sẽ hoạt động và tôi hoàn toàn không biết tại sao câu trả lời của anh ấy lại bị bỏ phiếu ...
if
yêu cầu một biểu thức Boolean, nó thậm chí sẽ không biên dịch với một int.
!=
hoạt động như một chất thay thế?