How come C# doesn't have a conditional XOR
operator?
Example:
true xor false = true
true xor true = false
false xor false = false
How come C# doesn't have a conditional XOR
operator?
Example:
true xor false = true
true xor true = false
false xor false = false
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.
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 !=
.
!=
would work for this. –
Mcgarry AND
and OR
but nothing as XOR
. or at least we didn't realize !=
:) @TheEvilGreebo –
Corpuz ^
also works for Booleans :| @Mcgarry https://mcmap.net/q/194706/-conditional-xor –
Corpuz ^^
operator, because I could have said a == b ^^ c == d
, but I can't get away with a == b != c == d
. I have to add parentheses. –
Brigidabrigit 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 ^.
^
, when used with boolean operands, is a boolean operator. "for the bool operands, the ^ operator computes the same result as the inequality operator !=". You can also bitwise-xor integer operands with ^
. C# is not C. –
Unroot 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.
^
and predates this one by five years. I doubt anything has changed. –
Succor 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;
CreateBool(1) & CreateBool(2)
will also yield False
. And that this is not sufficient if the CLR is roughed up a bit. But, as fun as this has been, in what scenario (where one hasn't plainly abused the CLR) does this distinction make any difference whatsoever? –
Soane i1
, just like a byte is). This is 100% defined and safe managed behavior. The CLR is not roughed-up.; The first time I saw this behavior was when using Microsoft Pex. –
Curator 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))
{
}
1
. This is a little known fact. You can end up in a situation where the xor of two non-false booleans is still non-false! That said in this particular code the xor operator is only ever applied to values in [0,1] so that my comment does not (fully) apply. –
Curator swift let firstBool: Bool = someExpression let secondBool: Bool = anotherExpression if (firstBool ^ secondBool) { println("Prints only if first or second, but not both") }
Not work as expected? –
Seda &
is also vulnerable. –
Curator &&
as if it were &
which is a miscompilation. –
Curator !=
operator :) –
Curator 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.
0101 ^ 0011
has the value 0110
. –
Gstring 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...
if
requires a Boolean expression, it won't even compile with an int. –
Soane © 2022 - 2024 — McMap. All rights reserved.
!=
work as a substitute? – Paracasein& | ^
) vs conditional operators (&& ||
). But you're right (of course), there is a logical XOR... – Scabies|
/&
and||
/&&
in C# is that the latter are short-circuiting while the former are not. As you also well know, this also means the latter are not usable for operand types which do not define a short-circuiting logic (operator
sfalse
andtrue
). <to be continued> – Dona|
and&
are for bit-wise operations whereas||
and&&
are for boolean operations. <to be continued> – Dona^
to mean bit-wise xor and^^
to mean boolean xor. And when noticing the existence of the^
operator and the lack of a corresponding^^
operator, their question is why there is no boolean version of xor, not why there is no short-circuiting version. <to be continued> – Dona