Logical XOR in C++

Logical XOR in C++

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 24164 Views - Last Post: 17 October 2014 - 11:03 AM Rate Topic: -----

#1 Tomas  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 1
  • View blog
  • Posts: 34
  • Joined: 12-June 07

Logical XOR in C++

Posted 22 February 2008 - 12:02 PM

Hi everybody

I have searched the net over and over and i cannot find a logical operator the performs the task of exclusive or in c++. If anyone knows of a logical operator in c++ that will perform this task, please let me know, as this is really bugging me and it would help to keep my programs a bit shorter and easier to read.

Thanks everybody

:ph34r: :^:

Is This A Good Question/Topic? 1
  • +

Replies To: Logical XOR in C++

#2 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,340
  • Joined: 20-August 07

Re: Logical XOR in C++

Posted 22 February 2008 - 12:28 PM

there isn't one. I'd suggest a function (or a macro, if you really have to)
template<typename T>
bool xor(const T& lhs, const T& rhs )
{
    return !( lhs && rhs ) && ( lhs || rhs );
} 

Was This Post Helpful? 3

#3 Tomas  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 1
  • View blog
  • Posts: 34
  • Joined: 12-June 07

Re: Logical XOR in C++

Posted 22 February 2008 - 01:15 PM

Thanks a lot
Was This Post Helpful? 0
  • +
  • -

#4 Dan J  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 4
  • Joined: 01-June 11

Re: Logical XOR in C++

Posted 01 June 2011 - 05:48 AM

There is. Just use the bitwise ^. It works fine for boolean statements, and no messy functions.

#include <iostream>
using namespace std;

int main()
{
	bool A = true;
	bool B = false;

	cout << A << " XOR " << A << " = ";
	if(A ^ A)
		cout << "True\n\n";
	else
		cout << "False\n\n";	//  <---------

	cout << A << " XOR " << B << " = ";
	if(A ^ B)/>
		cout << "True\n\n";	// <----------
	else
		cout << "False\n\n";

	cout << B << " XOR " << A << " = ";
	if(B ^ A)
		cout << "True\n\n";	// <----------
	else
		cout << "False\n\n";

	cout << B << " XOR " << B << " = ";
	if(B ^ B)/>
		cout << "True\n\n";
	else
		cout << "False\n\n";	// <----------
}


Was This Post Helpful? 2
  • +
  • -

#5 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Logical XOR in C++

Posted 01 June 2011 - 06:04 AM

Well, what's exactly wrong about operator != ? :P
Was This Post Helpful? 0
  • +
  • -

#6 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,340
  • Joined: 20-August 07

Re: Logical XOR in C++

Posted 01 June 2011 - 06:24 AM

View PostDan J, on 01 June 2011 - 01:48 PM, said:

There is. Just use the bitwise ^. It works fine for boolean statements, and no messy functions.
However there are many times when types other than bool (with values other than 0 or 1) are used in logical expressions, and the bitwise-XOR will not work for those. The most common example I can think of is std::istream derived types, which implicitly cast to void* in order to allow them to be used as part of a while or if expression; Aside from the fact that the ^ operator doesn't work on void* (it results in a compiler error), there's also no guarantee that a (void*) 'true' value would be equal to 1, therefore the bitwise-XOR may not yield the desired result.

You could of course cast those to bool first (or use a double-NOT !!), but then you're getting into messy syntax, so a template function would still be cleaner and more consistent.

This post has been edited by Bench: 01 June 2011 - 06:47 AM

Was This Post Helpful? 4
  • +
  • -

#7 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Logical XOR in C++

Posted 01 June 2011 - 06:33 AM

I concur. Actually, != and ^ will work different from logical_xor if other than bool values are given (still, I think != is much more readable/verbose than ^ ;) ) - you can always play with old C !! trick, but template function will be a lot more readable, and less confusing. :)

Quote

there's also no guarantee that a 'true' value would be equal to 1
- in this context you meant 'true' as in void* value, right? Then of course you're right.
Was This Post Helpful? 2
  • +
  • -

#8 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,340
  • Joined: 20-August 07

Re: Logical XOR in C++

Posted 01 June 2011 - 06:48 AM

View PostXupicor, on 01 June 2011 - 02:33 PM, said:

Quote

there's also no guarantee that a 'true' value would be equal to 1
- in this context you meant 'true' as in void* value, right? Then of course you're right.
Thanks - yes I meant for a void* value (I've corrected the original post)
Was This Post Helpful? 1
  • +
  • -

#9 Dan J  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 4
  • Joined: 01-June 11

Re: Logical XOR in C++

Posted 01 June 2011 - 07:03 AM

While != "will" work, realize that to write an XOR expression with it, you would have to write something like:

if( ( A && !B ) || ( !A && B ) )

A little messy, especially if the A and B in question are fairly long statements. Say whether a tile on a map were collidable, one might have to write (game->map->tiles[player->position->x][player->position->y]->Solid == true). Try fitting something like that four times on one line.

The ^ method I suggested does not "only work for bool types" because ultimately when you compare two conditions they will equate to a true or false. For example:

if( (X == 1) ^ (Y == 2) )

X == 1 equates to a true or false (1 or 0) depending on its outcome, as does Y == 2, so where's the problem?
Was This Post Helpful? 2
  • +
  • -

#10 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Logical XOR in C++

Posted 01 June 2011 - 07:07 AM

There's no problem then, but I feel != is more readable and will work the same in that situation.
edit: And you still have to remember to cast or either force the xor arguments to be of bool type. That's a bit error prone.

This post has been edited by Xupicor: 01 June 2011 - 07:10 AM

Was This Post Helpful? 0
  • +
  • -

#11 Dan J  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 4
  • Joined: 01-June 11

Re: Logical XOR in C++

Posted 01 June 2011 - 07:13 AM

View PostXupicor, on 01 June 2011 - 07:07 AM, said:

you still have to remember to cast or either force the xor arguments to be of bool type. That's a bit error prone.


Disagree. Any use of ==, !=, &&, or || will equate to a boolean value upon it's resolution, no matter what types are compared.

edit: To be fair, I do sometimes use !someinteger, to see if it's zero, or someinteger for non-zero. Perhaps things of that nature could cause problems when using bitwise operators. I still don't understand how you are suggesting the use of != though. That simply means "does not equal", not "exclusive or".

This post has been edited by Dan J: 01 June 2011 - 07:19 AM

Was This Post Helpful? 1
  • +
  • -

#12 Dan J  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 4
  • Joined: 01-June 11

Re: Logical XOR in C++

Posted 01 June 2011 - 07:26 AM

edit 2: I just checked, ints do work as bools and compare with ^. 0 being false, non-zero being true.

edit 3: omg, I get it now. Yeah, both arguments equate to a true or false, != will mean they have to be different, so both false and both true will equate false, while one or other will equate true. Yes, your way seems to make sense.

This post has been edited by Dan J: 01 June 2011 - 07:32 AM

Was This Post Helpful? 0
  • +
  • -

#13 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Logical XOR in C++

Posted 01 June 2011 - 07:54 AM

Perhaps I wasn't clear enough, I'll get some coffee and start again. ;)
So, for boolean values true != false and true ^ false will work the same. Look at the xor truth table, it pretty much spells "not equal". ;)
For other values, like int - you get different results with ^ and != - obviously, see 1 != 2 => true and 1 ^ 2 => 3. After you cast xor result to boolean value, then of course they'll be the same. But that still may not be what you want.

What I meant was that if you care about the result of the xor to be 1 or 0 *, then you need to cast or otherwise force it's arguments to be bool, or 1/0, by !!, or whatnot (pun intended :P). And if you did that, then at this point you can use either ^ or !=, since they work the same on boolean values (look above). :)

Now, about logical_xor - say you do 5 xor 6 - xor implemented as logical_xor would return false, as != would return true, and as ^ would return 3 (cast to bool and you get true). Which one would be the correct answer?

*) Not that you'd always care, but there are times and expressions that rely on funny things. :P

This post has been edited by Xupicor: 01 June 2011 - 07:57 AM

Was This Post Helpful? 2
  • +
  • -

#14 McSick  Icon User is offline

  • D.I.C Head

Reputation: 33
  • View blog
  • Posts: 179
  • Joined: 02-September 10

Re: Logical XOR in C++

Posted 02 June 2011 - 10:17 AM

I think it just boils down to what Xupicor says. Does the original poster want a logical xor or merely a not equals dealio. Logical xor results in a value of true if exactly one of the operands has a value of true. Now from int -> bool we know 0 = false and everything else = true. Hence 6 xor 5 would be false and != cannot be used. Of course I just like breaking xor up for better proof. Dan J said it already I think, but A xor B is logically equivalent to ( ( A && !B ) || ( !A && B ) ). My proposed function

bool xor(A,B)/>
{
  return ((A && !B)/> || (!A && B)/>)
}



Or something along the lines of this ^^
Was This Post Helpful? 3
  • +
  • -

#15 sbesch  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 16-October 14

Re: Logical XOR in C++

Posted 16 October 2014 - 01:54 PM

I don't want to sound like a trouble maker on my first post, but I'm afraid you are all wrong in essence. To wit, unless you want
to depend on compiler implementation and good user behavior, I would not suggest using any of the solutions given without qualification.

Unless you can guarantee that the values used for true and false will always be the same, then conditions can be found that will make them all fail. For example, calling a library that was compiled on a system using one value for "TRUE", from code compiled on a system using a different TRUE value. A simple example might be using -1 as true in one case and +1 in another. Assuming that false is zero, then the bitwise XOR will produce -2, not zero, or True, when the result should be false (0). I'm not even sure that I trust the same compiler on the same System to always use the same value for TRUE.

Even if you assume that all compilers on earth use the same standard values for true and false, I can pretty much guarantee that there will be some nutty user somewhere who will typecast and int to a boolean, then pass in all manner of non-zero values which when XOR'd will give non-zero results. In truth, the only guaranteed way to make this work is by writing an XOR function:
bool XOR (bool a, bool B)/>{
 int ba=a?1:0;
 int bb=b?1:0;
 return ((ba ^ bb)==0);
}


This still assumes that FALSE is zero, but I'm a lot more comfortable with that assumption than I am with the assumption that TRUE will always be the same positive value (such as 1). I agree that this is a pain. I agree that C++ should include this operator both for type safety and for cross compiler consistency. But it doesn't. Ah well
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2