RAC*_*RAC 274 c++ operators logical-operators
有这样的事吗?这是我第一次遇到它的实际需要,但我没有看到Stroustrup中列出的一个.我打算写:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Run Code Online (Sandbox Code Playgroud)
但是没有^^
运营商.我可以在^
这里使用bitwise 并得到正确的答案(无论机器表示真和假)?我从来没有拌&
和&&
,或|
和||
,所以我毫不犹豫地做到这一点与^
和^^
.
我会更自在地编写自己的bool XOR(bool,bool)
函数.
Gre*_*ill 507
该!=
运营商服务于这一目的的bool
值.
Lir*_*una 231
对于真正的逻辑XOR操作,这将起作用:
if(!A != !B) {
// code here
}
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 42
适当的手动逻辑 XOR实现取决于您希望模拟其他逻辑运算符(||
和&&
)与XOR 的一般行为的接近程度.关于这些运算符有两个重要的事项:1)它们保证短路评估,2)它们引入序列点,3)它们仅评估它们的操作数一次.
如您所知,XOR评估不能被短路,因为结果总是取决于两个操作数.所以1是不可能的.但是2呢?如果你不关心2,那么使用标准化(即bool
)值运算符!=
就结果执行XOR的工作.!
如果需要,操作数可以很容易地用一元标准化.因此!A != !B
在这方面实现了适当的XOR.
但是如果你关心额外的序列点,那么实现XOR的正确方法既不是!=
也不^
是按位.正确执行XOR(a,b)的一种可能方法可能如下所示
a ? !b : b
Run Code Online (Sandbox Code Playgroud)
这实际上就像你可以制作一个自制的XOR"相似" ||
和&&
.当然,只有将XOR实现为宏时,这才有效.函数不会这样做,因为排序不适用于函数的参数.
有人可能会说,虽然,具有每一个序列点的唯一原因&&
和||
是支持短路评价,从而XOR并不需要一个.实际上,这是有道理的.然而,值得考虑在中间进行具有序列点的XOR.例如,以下表达式
++x > 1 && x < 5
Run Code Online (Sandbox Code Playgroud)
已经在C/C++中定义了行为和特定结果(至少在排序方面).因此,可以合理地期望用户定义的逻辑 XOR相同,如
XOR(++x > 1, x < 5)
Run Code Online (Sandbox Code Playgroud)
而!=
基于a 的XOR没有这个属性.
Ber*_*een 26
还有另一种方法可以做XOR:
bool XOR(bool a, bool b)
{
return (a + b) % 2;
}
Run Code Online (Sandbox Code Playgroud)
显然可以证明通过以下方式工作:
#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;
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 18
XOR运算符不能短路; 即,仅通过评估其左手操作数,您无法预测XOR表达式的结果.因此,没有理由提供^^
版本.
ele*_*ice 13
发布了一些好的代码,比#!=!b更好地解决了问题
请注意,我必须添加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
Run Code Online (Sandbox Code Playgroud)
小智 5
我认为这是您在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
}
Run Code Online (Sandbox Code Playgroud)
证明
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
Run Code Online (Sandbox Code Playgroud)
证明是,对输入和输出的详尽研究表明,在两个表中,对于每个输入集,结果始终在两个表中相同。
因此,最初的问题是如何写:
return (A==5) ^^ (B==5)
Run Code Online (Sandbox Code Playgroud)
答案是
return (A==5) == !(B==5);
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,写
return !(A==5) == (B==5);
Run Code Online (Sandbox Code Playgroud)
(A || B) && !(A && B)
第一部分是A OR B,即Inclusive OR;第二部分是,NOT A AND B。你一起得到 A 或 B,但不能同时得到 A 和 B。
这将提供在下面的真值表中证明的 XOR。
|-----|-----|-----------|
| A | B | A XOR B |
|-----|-----|-----------|
| T | T | False |
|-----|-----|-----------|
| T | F | True |
|-----|-----|-----------|
| F | T | True |
|-----|-----|-----------|
| F | F | False |
|-----|-----|-----------|
Run Code Online (Sandbox Code Playgroud)