C ++中的逻辑异或运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1596668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Logical XOR operator in C++?
提问by RAC
Is there such a thing? It is the first time I encountered a practical need for it, but I don't see one listed in Stroustrup. I intend to write:
有这样的事情吗?这是我第一次遇到实际需求,但我没有看到Stroustrup 中列出的需求。我打算写:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
But there is no ^^
operator. Can I use the bitwise ^
here and get the right answer (regardless of machine representation of true and false)? I never mix &
and &&
, or |
and ||
, so I hesitate to do that with ^
and ^^
.
但是没有^^
运营商。我可以在^
这里使用按位并得到正确的答案(无论真假的机器表示如何)?我从不混合&
and &&
, or |
and ||
,所以我犹豫要不要用^
and ^^
。
I'd be more comfortable writing my own bool XOR(bool,bool)
function instead.
我会更舒服地编写自己的bool XOR(bool,bool)
函数。
回答by Greg Hewgill
The !=
operator serves this purpose for bool
values.
该!=
运营商服务于这一目的的bool
值。
回答by LiraNuna
For a true logical XOR operation, this will work:
对于真正的逻辑异或运算,这将起作用:
if(!A != !B) {
// code here
}
Note the !
are there to convert the values to booleans and negate them, so that two unequal positive integers (each a true
) would evaluate to false
.
请注意,!
有将值转换为布尔值并取反它们,以便两个不相等的正整数(每个 a true
)的计算结果为false
。
回答by AnT
Proper manual logicalXOR implementation depends on how closely you want to mimic the general behavior of other logical operators (||
and &&
) with your XOR. There are two important things about these operators: 1) they guarantee short-circuit evaluation, 2) they introduce a sequence point, 3) they evaluate their operands only once.
正确的手动逻辑XOR 实现取决于您想用 XOR 模拟其他逻辑运算符 (||
和&&
)的一般行为的程度。这些运算符有两个重要的事情:1)它们保证短路评估,2)它们引入了一个序列点,3)它们只评估它们的操作数一次。
XOR evaluation, as you understand, cannot be short-circuited since the result always depends on both operands. So 1 is out of question. But what about 2? If you don't care about 2, then with normalized (i.e. bool
) values operator !=
does the job of XOR in terms of the result. And the operands can be easily normalized with unary !
, if necessary. Thus !A != !B
implements the proper XOR in that regard.
如您所知,XOR 评估不能短路,因为结果始终取决于两个操作数。所以1是没有问题的。但是2呢?如果您不关心 2,那么使用归一化(即bool
)值运算符!=
就结果而言执行 XOR 的工作。!
如有必要,操作数可以很容易地用一元归一化。因此!A != !B
在这方面实现了适当的 XOR。
But if you care about the extra sequence point though, neither !=
nor bitwise ^
is the proper way to implement XOR. One possible way to do XOR(a, b) correctly might look as follows
但是,如果您关心额外的序列点,那么无论!=
是按位还是按位都不^
是实现 XOR 的正确方法。正确执行 XOR(a, b) 的一种可能方法可能如下所示
a ? !b : b
This is actually as close as you can get to making a homemade XOR "similar" to ||
and &&
. This will only work, of course, if you implement your XOR as a macro. A function won't do, since the sequencing will not apply to function's arguments.
这实际上与制作与||
和类似的自制 XOR 非常接近&&
。当然,这只有在您将 XOR 实现为宏时才有效。函数不会这样做,因为排序不适用于函数的参数。
Someone might say though, that the only reason of having a sequence point at each &&
and ||
is to support the short-circuited evaluation, and thus XOR does not need one. This makes sense, actually. Yet, it is worth considering having a XOR with a sequence point in the middle. For example, the following expression
不过,有人可能会说,在每个&&
和处都有一个序列点的唯一原因||
是支持短路评估,因此 XOR 不需要一个。这实际上是有道理的。然而,值得考虑在中间有一个序列点的异或。例如,下面的表达式
++x > 1 && x < 5
has defined behavior and specificed result in C/C++ (with regard to sequencing at least). So, one might reasonably expect the same from user-defined logicalXOR, as in
在 C/C++ 中定义了行为和特定结果(至少在排序方面)。因此,人们可能会合理地期望用户定义的逻辑XOR会得到相同的结果,如
XOR(++x > 1, x < 5)
while a !=
-based XOR doesn't have this property.
而!=
基于 -based XOR 没有这个属性。
回答by Bertie Wheen
There is another way to do XOR:
还有另一种方式进行异或:
bool XOR(bool a, bool b)
{
return (a + b) % 2;
}
Which obviously can be demonstrated to work via:
显然可以通过以下方式证明可以工作:
#include <iostream>
bool XOR(bool a, bool b)
{
return (a + b) % 2;
}
int main()
{
using namespace std;
cout << "XOR(true, true):\t" << XOR(true, true) << endl
<< "XOR(true, false):\t" << XOR(true, false) << endl
<< "XOR(false, true):\t" << XOR(false, true) << endl
<< "XOR(false, false):\t" << XOR(false, false) << endl
<< "XOR(0, 0):\t\t" << XOR(0, 0) << endl
<< "XOR(1, 0):\t\t" << XOR(1, 0) << endl
<< "XOR(5, 0):\t\t" << XOR(5, 0) << endl
<< "XOR(20, 0):\t\t" << XOR(20, 0) << endl
<< "XOR(6, 6):\t\t" << XOR(5, 5) << endl
<< "XOR(5, 6):\t\t" << XOR(5, 6) << endl
<< "XOR(1, 1):\t\t" << XOR(1, 1) << endl;
return 0;
}
回答by Mehrdad Afshari
The XOR operator cannot be short circuited; i.e. you cannot predict the result of an XOR expression just by evaluating its left hand operand. Thus, there's no reason to provide a ^^
version.
XOR 运算符不能短路;即您不能仅通过评估其左手操作数来预测 XOR 表达式的结果。因此,没有理由提供一个^^
版本。
回答by elegant dice
There was some good code posted that solved the problem better than !a != !b
发布了一些很好的代码,比 !a != !b 更好地解决了问题
Note that I had to add the BOOL_DETAIL_OPEN/CLOSE so it would work on MSVC 2010
请注意,我必须添加 BOOL_DETAIL_OPEN/CLOSE 以便它适用于 MSVC 2010
/* From: http://groups.google.com/group/comp.std.c++/msg/2ff60fa87e8b6aeb
Proposed code left-to-right? sequence point? bool args? bool result? ICE result? Singular 'b'?
-------------- -------------- --------------- ---------- ------------ ----------- -------------
a ^ b no no no no yes yes
a != b no no no no yes yes
(!a)!=(!b) no no no no yes yes
my_xor_func(a,b) no no yes yes no yes
a ? !b : b yes yes no no yes no
a ? !b : !!b yes yes no no yes no
[* see below] yes yes yes yes yes no
(( a bool_xor b )) yes yes yes yes yes yes
[* = a ? !static_cast<bool>(b) : static_cast<bool>(b)]
But what is this funny "(( a bool_xor b ))"? Well, you can create some
macros that allow you such a strange syntax. Note that the
double-brackets are part of the syntax and cannot be removed! The set of
three macros (plus two internal helper macros) also provides bool_and
and bool_or. That given, what is it good for? We have && and || already,
why do we need such a stupid syntax? Well, && and || can't guarantee
that the arguments are converted to bool and that you get a bool result.
Think "operator overloads". Here's how the macros look like:
Note: BOOL_DETAIL_OPEN/CLOSE added to make it work on MSVC 2010
*/
#define BOOL_DETAIL_AND_HELPER(x) static_cast<bool>(x):false
#define BOOL_DETAIL_XOR_HELPER(x) !static_cast<bool>(x):static_cast<bool>(x)
#define BOOL_DETAIL_OPEN (
#define BOOL_DETAIL_CLOSE )
#define bool_and BOOL_DETAIL_CLOSE ? BOOL_DETAIL_AND_HELPER BOOL_DETAIL_OPEN
#define bool_or BOOL_DETAIL_CLOSE ? true:static_cast<bool> BOOL_DETAIL_OPEN
#define bool_xor BOOL_DETAIL_CLOSE ? BOOL_DETAIL_XOR_HELPER BOOL_DETAIL_OPEN
回答by tiands
Use a simple:
使用一个简单的:
return ((op1 ? 1 : 0) ^ (op2 ? 1 : 0));
回答by Indinfer
Here is how I think you write an XOR comparison in C++:
以下是我认为您在 C++ 中编写 XOR 比较的方式:
bool a = true; // Test by changing to true or false
bool b = false; // Test by changing to true or false
if (a == !b) // THIS IS YOUR XOR comparison
{
// do whatever
}
Proof
证明
XOR TABLE
a b XOR
--- --- ---
T T F
T F T
F T T
F F F
a == !b TABLE
a b !b a == !b
--- --- --- -------
T T F F
T F T T
F T F T
F F T F
The proof is that an exhaustive study of inputs and outputs shows that in the two tables, for every input set the result is always the identical in the two tables.
证据是对输入和输出的详尽研究表明,在两个表中,对于每个输入集,两个表中的结果始终相同。
Therefore, the original question being how to write:
因此,最初的问题是如何写:
return (A==5) ^^ (B==5)
The answer would be
答案是
return (A==5) == !(B==5);
Or if you like, write
或者如果你喜欢,写
return !(A==5) == (B==5);
回答by Eat at Joes
(A || B) && !(A && B)
(A || B) && !(A && B)
The first part is A OR B, which is the Inclusive OR; the second part is, NOT A AND B. Together you get A or B, but not both A and B.
第一部分是A OR B,即Inclusive OR;第二部分是,NOT A AND B。你一起得到 A 或 B,但不能同时得到 A 和 B。
This will provide the XOR proved in the truth table below.
这将提供在下面的真值表中证明的异或。
|-----|-----|-----------|
| A | B | A XOR B |
|-----|-----|-----------|
| T | T | False |
|-----|-----|-----------|
| T | F | True |
|-----|-----|-----------|
| F | T | True |
|-----|-----|-----------|
| F | F | False |
|-----|-----|-----------|
回答by csiz
I use "xor" (it seems it's a keyword; in Code::Blocksat least it gets bold) just as you can use "and" instead of &&
and "or" instead of ||
.
我使用“xor”(它似乎是一个关键字;在Code::Blocks中至少它变得粗体)就像您可以使用“and”代替&&
和“or”代替||
。
if (first xor second)...
Yes, it is bitwise. Sorry.
是的,它是按位的。对不起。