views:

373

answers:

6

Off the top of my head, I cannot think of a single language I've used that had a logical exclusive or operator, but all have logical and bitwise and and or operators.

Looking around, the only reason to this that I could find was that exclusive or cannot be short circuited, so a logical version would be useless, which I really can't see being the case. The reason it came to my attention that most languages lack this is that I needed it (I was using Ruby, so I wrote a method to convert an integer to a boolean, and then use bitwise XOR, which on booleans acts like logical XOR).

Just using bitwise XOR does not work either, because it will give a different result.

0b0001  ^  0b1000 = 0b1001 (True)
0b0001 XOR 0b1000 = False
// Where ^ is bitwise exclusive or and XOR is logical exclusive or
// Using != (not equal to) also doesn't work
0b0001 != 0b1000 = True

So why is it that most languages do not include a logical exclusive or operator?

Edit: I added an example with how != also does not do what I want, it almost does, but falls into the same problem that using bitwise exclusive or does, it only works if you know that you are working with zero or one, and not any other number.

And to note, this is assuming that language uses zero as false and nonzero as true.

+3  A: 

The only reason I can think of is that the operation is relatively rare. I don't see why something like ^^ couldn't be assigned to it though, maybe people who design languages want to avoid operator clutter.

As to it being useless because it can't be short-circuited, in many strongly typed languages you can't use the bitwise XOR operator to compare booleans without casting back and forth, in which case even a non-short circuiting logical XOR would make sense to have.

Matti Virkkunen
+1  A: 

Probably because XOR isn't commonly needed as a logical operator, and you can do it almost as easily as this:

// foo xor bar
(foo & !bar) || (bar & !foo)

// or like this (assuming foo and bar are booleans)
!(foo==bar)

// assume boleans that can be cast as integers with true=1 and false=0
// foo XOR bar XOR baz XOR alice
((int)foo + (int)bar + (int)baz + (int)alice)&0b1
MadCoder
That will get complicated for three or four tests though.
Kinopiko
Yep, but it's just one of those things that's rare enough for language designers to not care about.
MadCoder
+11  A: 

Nearly every language has a logical XOR. The symbol they use for it varies, but regardless of the symbol, most people pronounce it "not equal".

Edit: for those who doubt, test code for three variables:

#include <iostream>

int main() { 
    for (int i=0; i<2; i++)
        for (int j=0; j<2; j++)
            for (int k=0; k<2; k++) {
                std::cout << "\n!=" << (i!=j!=k);
                std::cout << "\t^ " << (i^j^k);
            }
    return 0;
}
Jerry Coffin
+0.5 for good answer. +0.5 for appropriate snarkiness.
Donnie DeBoer
If you can't guarantee a boolean context, that is asking for subtle bugs.
Craig McQueen
most languages have a bitwise XOR, but not a **logical** one. "not equal" works the same in the case of tow operands, but I don't think a!=b!=c is equivalent to a XOR b XOR c.
MadCoder
And the inverse operation is *equivalence*, or simply *equals*.
Loadmaster
@Craig McQueen:the only possible room for disagreement is about whether the bugs will (necessarily) be subtle!
Jerry Coffin
@MadCoder, `!=` is a XOR when both operands are boolean. And yes, `a != b != c` is exactly equivalent to `a XOR b XOR c` if all operands are boolean.
Pavel Minaev
Yep, I'm wrong. Still, having an explicit XOR operator could address Craig's concerns as the operands could be cast to booleans automatically.
MadCoder
@MadCoder:There are undoubtedly circumstances under which it would be handy. OTOH, I can think of a lot of other operators I'm pretty sure I'd use a lot more often.
Jerry Coffin
Added an example of how `!=` isn't a replacement for logical XOR. Oddly, it's the same example as before, except I put `!=` in there.
Jeffrey Aylesworth
@Jeffrey:Yes, it's a *Boolean* XOR, so you have to ensure that the values are Boolean before you apply it to them. Since reversing them doesn't matter, you can use `!a != !b`;
Jerry Coffin
+4  A: 

What do you mean by "logical XOR operator"? I'm not sure what result do you expect from your examples, but here's my answer:

a (logical XOR) b is the same as bool(a) != bool(b)

Inequality is a logical XOR. Since you already have the bitwise XOR version, you don't need a special operator for the logical one.

viraptor
+3  A: 

OK, so you're looking for a bytewise exclusive-or versus a bitwise exclusive-or. It seems like you're looking for something that will operate on a byte as "on" or "off", as thought the bytes are "0" or "nonzero", then XOR them. It really sounds like you're looking to compress each byte into a single bit indicating true or false. So, it sounds like you want (a!=0)^(b!=0)

 a  b    a YOURXOR b    a!=0   b!=0   (a!=0)^(b!=0)
 0  0         0          0       0        0        
 0  1         1          0       1        1
 1  0         1          1       0        1
 7  0         1          1       0        1
 0  7         1          0       1        1
 3  7         0          1       1        0
 7  3         0          1       1        0
 7  7         0          1       1        0

As for why that's not in every language... that I can't really answer. However it's not all that difficult to implement with the building blocks of bitwise xor available in every language, and no language offers all possible functionality - they just offer enough to let you build the extended functionality you might need. Oh, and if this were a popular enough problem, you'd expect to see libraries or macros all over the place for it; while I may not have made a sufficient search for such libs/code, I didn't find any myself, indicating that the requirement is either trivial to write, or a niche requirement.

atk
I think !a^!b works too. In particular it works in Ruby as `!x` is a bool
gnibbler
+4  A: 

You can also write !a ^ !b to get the same effect as a logical xor.

You probably don't find logical xor in programming languages because:

  • it doesn't generate very efficient assembly code
  • is not needed very often
  • language designers have to put the line somewhere, why not NAND, NOR, NXOR, etc.
cdiggins
+1 because I liked the have to draw the line somewere point
mikek3332002