Recently I had occasion to write something like the following code:
if ((!x && (y & z)) || (x && !(y & z))
something();
Which would have been simpler as:
if (x ^^ (y & z))
something();
If there was such a thing as a '^^' operator. Does anyone know why C left
out the logical XOR operator?
--
D'Arcy J.M. Cain (darcy@druid) |
D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay
West Hill, Ontario, Canada | of operating systems.
+ 416 281 6094 |
I can envisage two reasons:
- It looks like && and ||, so it should short-circuit.
This doesn't make sense for XOR.
- What's wrong with saying:
!!x ^ !!y
which accomplishes exactly what you want.
I'm tempted to use the phrase "insufficient utility".
- Cameron Simpson
cam...@spectrum.cs.unsw.oz.au
The C standard left it out because it hasn't been part of C,
and it wouldn't address a severe deficiency, which was the only
valid reason for adding functionality during standardization.
The reason that C hasn't had a "logical exclusive-or operator"
is that it would serve no real purpose. The reason for specific
"logical and" and "logical or" operators is to obtain the short-
circuit effect; obviously a "logical exclusive-or" would not be
able to short-circuit.
If you really feel like you need one, you can define your own:
#define XOR(a,b) (((a)!=0 ^ (b)!=0) & 1) /* for example */
BTW, did you mean y & z or y && z?
My first thought was, What about
if ( x ? !(y&z) : (y&z) )
Hmm, still pretty ugly, though at least it doesn't repeat both tests.
I could write it
if ( (y&z) ? !x : x )
to repeat only the shorter test. However ...
Buzzing around in the back of my head, like a bluebottle at a dusty
window, was the idea of capitalizing on the fact that ! returns 1 or 0
always. Okay, I thought, y&z may as well be replaced by a single
variable, so set yz for y&z (or y&&z). Now the expression is
if ( (!x && yz) || (x && !yz) )
A quick truth table, using 1 to mean "anything non-zero".
x yz !x !yz desired result
1 1 0 0 0
1 0 0 1 1
0 1 1 0 1
0 0 1 1 0
Hmm, looks mighty familiar. In fact the desired result is !x ^ !yz, or in
the original terms of the problem,
if ( !x ^ !(y & z) )
So the reason there's no "logical exclusive or" is that bitwise exclusive
ORing the negated quantities gives the same result.
BTW, (1) I'd probably comment that !^! construction, because it looks
weird, and (2) I'd ask somebody else to review it to make sure I didn't
have some dumb goof. (3) On proofreading this posting, I think I'd
probably go back to my first thought, above, because IMHO it's clearer.
Stan Brown, Oak Road Systems, Cleveland, Ohio, U.S.A. (216) 371-0043
The opinions expressed are mine. Mine alone! Nobody else is responsible for
them or even endorses them--except my cat Dexter, and he signed the power of
attorney only under my threat to cut off his Cat Chow!
Try `!x != !(y & z)', which gets the same results; if the operands are
booleans to begin with, you can leave out the unary !s.
"^^" is a perennial suggestion which really has very little to recommend
it. It can't short-circuit like && and ||, because XOR has to evaluate
both operands. And it would be useful rather rarely.
--
TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology
OSI: handling yesterday's loads someday| he...@zoo.toronto.edu utzoo!henry
Except adding it would stop the perennial questions as to why there's not
a logical XOR operator :-)
--
Brian L. Matthews b...@6sceng.UUCP
As has been pointed out, == and != are essentially
"logical" EQV and XOR, and hence logical XOR is redundant.
The use of unary "!" is necessary if either operand
is not guaranteed to be in the range 0..1.
S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA 02138
>From article <1990Sep12.1...@druid.uucp>, by da...@druid.uucp (D'Arcy J.M. Cain):
>| [ essentially, the expression
(!x && y) || (x && !y) ]
>| If there was such a thing as a '^^' operator. Does anyone know why C left
>| out the logical XOR operator?
>I can envisage two reasons:
> - It looks like && and ||, so it should short-circuit.
> This doesn't make sense for XOR.
Sure it does. Short circuit simply means that as soon as the value of
the expression can be determined, no further expressions should be
evaluated. An exclusive or expression can't be determined without
evaluating both sub-expressions, but that doesn't mean that it isn't
short circuited.
> - What's wrong with saying:
> !!x ^ !!y
> which accomplishes exactly what you want.
What? If x = y = 1, then !!x = !!y = 1, and 1 ^ 1 = 1, but x ^^ y = 0.
> I'm tempted to use the phrase "insufficient utility".
I can agree with you here. Certainly I haven't needed an exclusive or
operator as much as I need && and ||. Nonetheless, the decision was,
we must admit, more pragmatic than elegant. The logical operator set
is neither complete nor minimal (nands, anyone? :-). If you like,
simply use Lisp, or C++, or [ ... ], and create the exclusive or
yourself. C doesn't have it, probably never will.
--
John Lacey, jo...@basho.uucp, or basho!jo...@cis.ohio-state.edu
Run that by me again? `1 ^ 1 = 1' ? You sure learnt logic in a different
school from me. Of course, one can be even terser and say
!x ^ !y
instead of
!!x ^ !!y
but the effect is the same.
- Cameron Simpson
cam...@spectrum.cs.unsw.oz.au
And ^^=, and &&=, and ||=.