Conditional XOR?
How come C# doesn't have a conditional XOR
operator?
Example:
true xor false = true
true xor tru开发者_运维知识库e = false
false xor false = false
Conditional xor should work like this:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
But this is how the !=
operator actually works with bool types:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
So as you see, the nonexistent ^^
can be replaced with existing !=
.
In C#, conditional operators only execute their secondary operand if necessary.
Since an XOR must by definition test both values, a conditional version would be silly.
Examples:
Logical AND:
&
- tests both sides every time.Logical OR:
|
- test both sides every time.Conditional AND:
&&
- only tests the 2nd side if the 1st side is true.Conditional OR:
||
- only test the 2nd side if the 1st side is false.
There is the logical XOR operator: ^
Documentation: C# Operators and ^ Operator
The documentation explicitly states that ^
, when used with boolean operands, is a boolean operator.
"for the bool operands, the ^ operator computes the same result as the inequality operator !=".
(And as noted in another answer, that's exactly what you want).
You can also bitwise-xor integer operands with ^.
Just as a clarification, the ^ operator works with both integral types and bool.
See MSDN's ^ Operator (C# Reference):
Binary ^ operators are predefined for the integral types and bool. For integral types, ^ computes the bitwise exclusive-OR of its operands. For bool operands, ^ computes the logical exclusive-or of its operands; that is, the result is true if and only if exactly one of its operands is true.
Maybe the documentation has changed since 2011 when this question was asked.
As asked by Mark L, Here is the correct version:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Here is the truth table:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Reference: Exclusive OR
Oh yes, it does.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
Conditional xor doesn't exist, but you can use logical one because xor is defined for booleans, and all conditional comparisons evaluate to booleans.
So you can say something like:
if ( (a == b) ^ (c == d))
{
}
While there is a logical xor operator ^
, there is no conditional xor operator. You can achieve a conditional xor of two values A and B using the following:
A ? (!B) : B
The parens are not necessary, but I added them for clarity.
As pointed out by The Evil Greebo, this evaluates both expressions, but xor cannot be short circuited like and and or.
you can use:
a = b ^ c;
just like in c/c++
There is no such thing as conditional (short-circuiting) XOR. Conditional operators are only meaningful when there's a way to definitively tell the final outcome from looking at only the first argument. XOR (and addition) always require two arguments, so there's no way to short-circuit after the first argument.
If you know A=true, then (A XOR B) = !B.
If you know A=false, then (A XOR B) = B.
In both cases, if you know A but not B, then you don't know enough to know (A XOR B). You must always learn the values of both A and B in order to calculate the answer. There is literally no use case where you can ever resolve the XOR without both values.
Keep in mind, XOR by definition has four cases:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Again, hopefully it's obvious from the above that knowing the first value is never enough to get the answer without also knowing the second value. However, in your question, you omitted the first case. If you instead wanted
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
then you can indeed get that by a short-circuiting conditional operation:
A && !B
But that's not an XOR.
NOTE: I know XOR and XNOR are bitwise operations, but considering the thing we are questioning here...
Ain't this work as conditional (boolean) XOR?
bool Xor(bool a, bool b){ return a != b }
a | b | x |
---|---|---|
False | False | False |
False | True | True |
True | False | True |
True | True | False |
Also I believe you can loop though data, aggregate them to use more than two operator. and still get the same result as Bitwise of Nth operand in same conditional manner
This question has been affectively answered, but I came across a different situation. It's true that there is no need for a conditional XOR. It's also true that the ^ operator can be used. However, if you need to only test the "true || false" status of the operands then ^ can lead to trouble. For example:
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...
}
}
In this example, if left is set to 10 (0xa) and right is set to 5 (0x5) the "success" branch is entered. For this (simplistic if silly) example, this would result in a bug since you shouldn't turn left AND right at the same time. What I gathered from the questioner is not that he actually wanted a conditional, but a simple way to perform the true/false on the values as passed to the xor.
A macro could do the trick:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Feel free to slap me around if I'm off the mark :o)
I read jimreed's answer below after I posted this (bad Yapdog!) and his is actually simpler. It would work and I have absolutely no idea why his answer was voted down...
精彩评论