90

How come C# doesn't have a conditional XOR operator?

Example:

true  xor false = true
true  xor true  = false
false xor false = false
david.s
  • 10,853
  • 5
  • 48
  • 80
Gilad Naaman
  • 5,828
  • 14
  • 48
  • 78
  • 16
    How does `!=` work as a substitute? – Pascal Cuoq Jun 28 '11 at 14:14
  • 45
    C# *does* have an xor operator ( x ^ y ). I therefore deny the premise of the question. Can you explain why you believed that C# does not have an xor operator? I am interested to learn why people believe false things about C#. – Eric Lippert Jun 28 '11 at 14:15
  • 3
    @Eric Lippert: I think he's referring to logical operators (`& | ^`) vs conditional operators (`&& ||`). But you're right (of course), there is a logical XOR... – BoltClock Jun 28 '11 at 14:15
  • 14
    @BoltClock: Oh, if the question is "why is there no short-circuiting xor operator?" -- how could there be? With "and" if the first argument is false you don't need to evaluate the second. With "or", if the first argument is true then you don't need to evaluate the second. You always need to evaluate both arguments for xor, so there is no short circuiting possible. – Eric Lippert Jun 28 '11 at 14:18
  • @Eric: Looks like that'd be the (The Evil Greebo's) answer. – BoltClock Jun 28 '11 at 14:19
  • 4
    The question itself is one better suited to Microsoft - and so that's a decent reason to downvote - but if whoever downvoted it did so because of the ^ operator, then you need to read with more attention to detail, because the question was conditional vs. logical, not simply "why isn't there an XOR". – The Evil Greebo Jun 28 '11 at 14:21
  • 2
    All the answers even the accepted one are thoroughly incorrect. If I answer the question correctly, can my answer be selected as the best answer? – Simple Fellow Oct 16 '15 at 13:32
  • 1
    @SimpleFellow, I'm intrigued. Why not post an answer, and find out? – Marc L. Dec 21 '15 at 22:05
  • @ Marc L. Ok as you asked. – Simple Fellow Dec 29 '15 at 10:27
  • Seems like there's a lot of confusion and debate about the logical ^ operator in the answers, which is odd since MS has kept this consistently well documented for every VS version since 2003, complete with code examples: https://msdn.microsoft.com/en-us/library/zkacc7k1(v=vs.71).aspx – joelmdev Nov 04 '16 at 16:02
  • Note that the question asked is WHY - not how do I make one. – The Evil Greebo May 31 '17 at 12:28
  • @EricLippert: It's been a few years, and maybe you know by now, but as it hasn't been posted here explicitly I'd like to respond to your comments about people believing false things about C# and about the question being about a short-circuiting xor operator. As you well know, the difference between `|`/`&` 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`s `false` and `true`). – Tom Sep 29 '19 at 11:40
  • @EricLippert : Because when dealing with boolean conditions the short-circuiting version is most often desired (and is the de facto standard, taught ubiquitously, with many textbook examples not mentioning the other version at all), and because for bit-wise operations on the common numeric types only the non-short-circuiting version of the operators is available, in practice what happens is that users of the language naturally develop the misconception that `|` and `&` are for bit-wise operations whereas `||` and `&&` are for boolean operations. – Tom Sep 29 '19 at 11:40
  • @EricLippert : Under this misconception, people are not even aware of the distinction between short-circuiting and non-short-circuiting (albeit they might be aware that the boolean versions of the operators do short-circuit while the bit-wise versions do not). And under this misconception, people expect `^` 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. – Tom Sep 29 '19 at 11:40
  • @EricLippert : So to summarise, the reason is that the short-circuiting distinction is quite implicit, that is it's not obvious or evident from typical usage examples alone. Clarification: I'm not saying it's not a good distinction, not a good choice of operators, or that the design of the language around this feature is flawed in any way. Just that it's a bit unreasonable to expect average users of the language to be aware of such subtleties. – Tom Sep 29 '19 at 11:40

11 Answers11

293

Question is a bit outdated but...

It's how this operator should work:

true xor false = true
true xor true = false
false xor true = true
false xor false = false

This is how != operator works with bool types:

(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false

So as you see unexisting ^^ can be replaced with existing !=

Jetroid
  • 25
  • 7
piotrpo
  • 11,607
  • 7
  • 38
  • 57
  • 49
    This is actually the only answer that addresses the question directly and correctly. – usr Mar 22 '13 at 14:31
  • 44
    I am sitting here facepalming myself that I didn't realize `!=` would work for this. – AdamMc331 Aug 19 '15 at 15:49
  • 1
    The answer is correct but the comments aren't. It does not address the question, which is "why doesn't C# have a conditional XOR?". Strictly speaking this isn't a logical operator, it's a relational equality operator. While the result is the same as XOR, it is in a different class. It only compares to XOR when testing two boolean values, and both sides of the operator still must be evaluated. – The Evil Greebo May 17 '17 at 02:22
  • 3
    @TheEvilGreebo - What you say is true; the != operator is not technically a conditional XOR operator. However, this answer effectively says, "A conditional XOR operator doesn't exist because the != operator does." That's how I read it, anyway. – Syndog May 22 '17 at 17:33
  • 6
    I think pretty much every one ended up to this post actually wanted to write XOR on Booleans. like there is logical `AND` and `OR` but nothing as `XOR`. or at least we didn't realize `!=` :) @TheEvilGreebo – M.kazem Akhgary Dec 26 '17 at 13:47
  • 1
    I just realized `^` also works for Booleans :| @AdamMc331 https://stackoverflow.com/a/37789115/4767498 – M.kazem Akhgary Dec 26 '17 at 13:50
127

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.

mdm
  • 11,962
  • 5
  • 31
  • 53
The Evil Greebo
  • 6,530
  • 3
  • 26
  • 54
  • 40
    An XOR operator would not violate the convention "conditional operators only execute their secondary operand if necessary". It would just always be necessary. – Nathan Kovner Dec 18 '15 at 21:57
  • 2
    Conditional XOR could be a nice and elegant shortcut for some particular patterns, although not sure if justified enough to include it in the language. An example of such patterns where XOR might prove useful, is Conditional Negation: When a Boolean expression should be negated or not, given a second boolean expression. – SalvadorGomez May 05 '16 at 22:21
  • 1
    Haven't responded to this in some time but to respond to popular comment by @KhyadHalda : Why would you ever build something you know would never be used? You'd be deliberately writing dead code. – The Evil Greebo May 15 '17 at 18:47
  • Given that a conditional XOR operator wouldn't violate the convention you define (Khyad's comment), coupled with the fact that it would actually be useful in some cases, it pretty much negates any "silliness" you ascribe to such an operator existing. – Syndog May 22 '17 at 17:06
  • 2
    How, ever, would a conditional XOR ever be useful? A conditional XOR cannot ever evaluate without comparing both sides to determine that they are or are not equal. Even the notion of a conditional XOR comparing two bools must still check the value of each bool and test the equality. – The Evil Greebo May 28 '17 at 22:35
  • Addendum - in the suggested case where you must negate a boolean, in c#, with a conditional XOR, how would you write that? given bool b1 and bool b2 if b1 must equal !b2 then b1 = !b2 is an assignment of an inversion. The "conditional xor" version would do what? b1 = (true ^ b2) ? If so that would be assignment of the result of a comparison of both sides, which doesn't seem like any kind of shortcut to the simpler assign the inversion. – The Evil Greebo May 28 '17 at 22:45
  • 1
    It's as silly as a conditional addition operator. Why not make another operator for conditional addition, where (a+b) only evaluates b when b is necessary? Just like with conditional XOR, this wouldn't violate the convention of conditional operators, it's just that the second argument would always be necessary. There's no use case for this ever. And I'm not just being pedantic with this example -- the XOR operation is essentially a 1-bit addition. – Kevin Holt May 15 '19 at 21:16
  • @TheEvilGreebo The boolean negation pattern described is not "b1 = !b2", but rather "if(b2) b1 = !b1; if(b1) { code }". I came here seeing if there was a clean way to do this without reassigning to b1, since it slightly offends my immutability aesthetic. Conditional xor would be one way of achieving that: "if(b1 ^^ b2) { code }". – Danwizard208 Jan 09 '20 at 00:56
  • No that would not enforce a conditional or (xor) state. If (b2) {b1 = !b1} would simply cause b1 to change its state if b2 were true. If b1 were already 0 then you'd end up with b2 and b1 both being 1 which would not meet the conditional xor enforcement being discussed. – The Evil Greebo Jan 10 '20 at 11:13
31

There is the logical XOR operator: ^

Documentation: C# Operators and ^ Operator

iceaway
  • 978
  • 1
  • 6
  • 12
  • 2
    Logical, not conditional. Logical and = &, conditional and = &&. He's asking about Conditional. – The Evil Greebo Jun 28 '11 at 14:16
  • 3
    It is binary, not logical. It assumes that bools are either 0 or 1 which is not true on the CLR. – usr Mar 22 '13 at 14:29
  • 1
    sorry, this answer does not actually answer the question about CONDITIONAL operators. this is a bit opperator – Nathan Tregillus Apr 14 '17 at 16:14
  • 3
    For the record, the documentation linked in this answer 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 !=". You can also bitwise-xor integer operands with `^`. C# is not C. – 15ee8f99-57ff-4f92-890c-b56153 May 17 '19 at 13:31
25

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.

jpmc26
  • 23,237
  • 9
  • 76
  • 129
RichardCL
  • 1,377
  • 9
  • 9
  • 2
    been programming in c# a long time, never knew this! thanks @RichardCL ! – Nathan Tregillus Apr 14 '17 at 16:19
  • This is good information but seems more appropriate as a comment or edit to the other answer that mentions `^` and predates this one by five years. I doubt anything has changed. – Chris Jul 30 '19 at 19:49
13

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

Simple Fellow
  • 3,641
  • 2
  • 20
  • 31
  • 3
    The question asked was WHY doesn't C# have a conditional XOR operator. This does not answer the question. As to the function itself: this function does operate as conditional XOR - however the question is, is it more efficient than the non-conditional XOR? In order to test for exclusive truth, XOR must confirm that one and exactly one result is true. This means both sides must be evaluated and compared. The function above tests both sides of an and condition while inverting one value, at a minimum. Do we know internally if this is any different than XOR? – The Evil Greebo May 31 '17 at 12:27
6

Oh yes, it does.

bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
Armen Tsirunyan
  • 120,726
  • 52
  • 304
  • 418
  • 1
    It is a binary operator, not a logical one. It assumes that bools are either 0 or 1 which is not true on the CLR. So this code can actually fail to work. – usr Mar 22 '13 at 14:30
  • 7
    @usr, In C#, the ^ operator is logical when applied to two Boolean operands. You commented an awful lot through these answers, did you ever run any code to test your hypothesis? – Marc L. Mar 28 '14 at 21:26
  • 2
    @MarcL. I did: http://pastebin.com/U7vqpn6G Prints true, although true ^ true is supposed to be false. bool is *not* always equal to 0 or 1. It is not a logical type on the CLR. It is an 8 bit quantity with arbitrary contents. I could have generated verifiable IL to demonstrate the issue as well. – usr Mar 28 '14 at 22:42
  • @usr, okay, so you've managed to show the logical operators appear to act on Booleans by applying bitwise to the underlying 8-bit value--for the record, `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? – Marc L. Mar 29 '14 at 05:23
  • 2
    When using other CLR languages than C# for example. I repeat: I could have used ILASM to create a fully verifiable, safe assembly that does this (at the IL level a boolean value is just an `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. – usr Mar 29 '14 at 10:11
  • 1
    @EdPlunkett , I don't think your truck is with me. usr showed that internally it is in fact a *binary* operator. The "abuse" of which I complained was the means by which he proved it, which I still maintain is too edgy. It may happen, but puts the use of Boolean so thoroughly into no-man's land that to deploy it as CLR-safe would be dangerous at best, abusive (if not malicious) at worst, and should be treated as a bug. What usr proves is that internally C# is more like C than either of us thought. Whether code that does this should be considered valid is another question. – Marc L. May 20 '19 at 16:33
  • @MarcL. Whoops, you're quite correct. I somehow failed to notice your comment that says "In C#, the ^ operator is logical when applied to two Boolean operands.", and I didn't read the comment I did reply to very closely. My apologies! – 15ee8f99-57ff-4f92-890c-b56153 May 20 '19 at 16:36
4

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))
{

}
Klark
  • 7,530
  • 3
  • 32
  • 59
  • It is a binary operator, not a logical one. It assumes that bools are either 0 or 1 which is not true on the CLR. So this code can actually fail to work. – usr Mar 22 '13 at 14:30
  • @usr what do you mean CLR? This worked for me, not sure if I missed an edge case here... – LunaCodeGirl Mar 30 '15 at 16:04
  • 3
    @Spencevail you probably were not thinking about the case that a non-false boolean might not have integer representation `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. – usr Mar 30 '15 at 16:09
  • @usr when would a boolean expression evaluate to something other than 0 or 1? Again, not disagreeing, just looking for more info on the subject. Would something like: ```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? – LunaCodeGirl Mar 30 '15 at 19:21
  • 1
    @Spencevail that is exactly the case that can fail. It is possible to create a safe managed code function CreateBool(byte) that converts a byte into a bool of the same bits. Then, CreateBool(1) ^ CreateBool(2) is true, but CreateBool(1) is true and CreateBool(2) is true as well! `&` is also vulnerable. – usr Mar 30 '15 at 19:27
  • 1
    Actually, I just reported a RyuJIT bug because they did not consider this possibility and compiled `&&` as if it were `&` which is a miscompilation. – usr Mar 30 '15 at 19:31
3

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.

jimreed
  • 382
  • 3
  • 4
  • What's the difference between a logican ^ and a conditional ^ ? oO – Armen Tsirunyan Jun 28 '11 at 14:28
  • @Armen Tsirunyan The logical operators perform bitwise operations in types where that makes sense while the conditional operators operate on boolean values and return a boolean result. Considering boolean values: `0101 ^ 0011` has the value `0110`. – jimreed Jun 28 '11 at 14:42
  • 3
    no, you are completely wrong. there are both types of XOR's (they're called bitwise and logical, respectively) in C#. Both use the ^ symbol. – Armen Tsirunyan Jun 28 '11 at 15:10
1

you can use:

a = b ^ c;

just like in c/c++

gulyan
  • 652
  • 5
  • 15
0

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.

Kevin Holt
  • 665
  • 7
  • 13
  • I’m not seeing anything in this answer that isn’t in at least one answer above. I don’t see any indication that your short-circuitable un-xor is what OP was looking for, since he accepted an answer which assumes he wanted proper xor. – 15ee8f99-57ff-4f92-890c-b56153 May 16 '19 at 01:04
  • Mine is literally the only answer suggested so far that can produce the OP's requested truth table without evaluating the second argument. – Kevin Holt May 17 '19 at 04:56
  • Also the OP asked why there is no conditional XOR, and while the answers above do say correctly that it's because XOR requires two arguments, IMO the answers above didn't seem to say sufficiently explain WHY does XOR actually need two arguments. Obviously you feel otherwise, but to me it was apparent from the various comments on this page that the basic two-argumentness of XOR hadn't been fully explained to a complete beginner yet. – Kevin Holt May 17 '19 at 05:21
  • 1
  • @Kevin Holt - Logical XOR is meaningful if you need one of the conditions to be true but not both. That you have to evaluate both conditions doesn't matter. The short circuit thing is a low level detail that you only have to worry about when dealing with performance critical code (control flow is slow). I'd be more concerned with what 'exclusive or' is supposed to mean when making a logical operator out of it. Namely, have it operate like the bitwise version (like the other operators), or make it an or that's exclusive (as many conditions as you want, but only one can be true). – Thorham Oct 04 '19 at 13:35
  • First off, short-circuits are not just for performance critical code. For example, "wroteFile = (FileOutputIsEnabled && TryToWriteTheFile().WasSuccessful())" is completely legal code, with drastically different outcomes for short-circuiting AND vs non-short-circuiting AND. Sure, performance is another (more common) way to use it, but it's by no means the only use of it. – Kevin Holt Oct 07 '19 at 17:37
  • Second, there is no such thing as short-circuiting XOR. Let's clarify what you mean by "you need one of the conditions to be true but not both". Do you mean "you need at least one of the conditions to be tru?" Because that's an OR, not an XOR, and yes there is a short-circuiting version of that. Do you mean "you need exactly one of the conditions to be true, but not neither and not both?" Because that needs to know both input values, and there's no way to short-circuit it. The only way to get a short-circuited XOR is if you short-circuit something other than XOR and call it XOR by mistake. – Kevin Holt Oct 07 '19 at 17:41
-3

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...

Yap Dog
  • 153
  • 1
  • 4
  • 3
    This is a C# question, not C/C++. `if` requires a Boolean expression, it won't even compile with an int. – Marc L. Mar 28 '14 at 21:24