C ++中的逻辑XOR运算符?
有这样的事吗? 这是我第一次遇到它的实际需求,但我没有看到在Stroustrup中列出的一个。 我打算写:
// Detect when exactly one of A,B is equal to five. return (A==5) ^^ (B==5);
但是没有^^
运算符。 我可以在这里使用按位,并得到正确的答案(不pipe机器表示真假)? 我从不混合&
和&&
或|
和||
,所以我犹豫要用^
和^^
来做这个。
我会更舒适的写我自己的bool XOR(bool,bool)
function。
!=
运算符为bool
值提供此目的。
对于真正的逻辑异或操作,这将起作用:
if(!A != !B) { // code here }
正确的手动逻辑 XOR实现取决于你想用你的异或模拟其他逻辑运算符( ||
和&&
)的一般行为。 这些运营商有两个重要的事情:1)他们保证短路评估,2)他们引入一个序列点,3)他们只评估一次操作数。
如您所知,XOR评估不能被短路,因为结果总是取决于两个操作数。 所以1是没有问题的。 但是2呢? 如果你不关心2,那么用规范化的(即bool
)值操作符!=
就结果而言,XOR的工作。 操作数可以很容易地用一元规范化!
,如有必要。 因此!A != !B
在这方面实现了正确的XOR。
但是,如果你关心额外的序列点,那么既不是按位,也不是实现异或的正确方法。 正确执行XOR(a,b)的一种可能方式可能如下所示
a ? !b : b
这实际上是尽可能靠近自制XOR与“相似”的 和&&
。 当然,如果将XOR实现为macros,这只会起作用。 函数不会做,因为sorting不适用于函数的参数。
有人可能会说,每个&&
和||
都有一个序列点的唯一原因 是支持短路评估,因此XOR不需要一个。 实际上这是有道理的。 然而,值得考虑的是在中间有一个序列点的XOR。 例如,下面的expression式
++x > 1 && x < 5
已经在C / C ++中定义了行为和具体的结果(至less在测序方面)。 所以,可以合理地期望从用户定义的逻辑 XOR相同,如在
XOR(++x > 1, x < 5)
而基于!=
的XOR没有这个属性。
还有另一种方法来做XOR:
bool XOR(bool a, bool b) { return (a + b) % 2; }
哪些显然可以certificate通过工作:
#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; }
异或运算符不能被短路; 即只通过评估其左手操作数就无法预测XORexpression式的结果。 因此,没有理由提供^^
版本。
有一些很好的代码发布,比!!!!更好的解决了这个问题
请注意,我必须添加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
使用一个简单的:
return ((op1 ? 1 : 0) ^ (op2 ? 1 : 0));
我使用“xor”(它似乎是一个关键字;在Code :: Blocks中 ,至less它是粗体),就像你可以使用“和”而不是&&
和“或”来代替||
。
if (first xor second)...
是的,这是按位。 抱歉。
下面是我认为你在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 }
certificate
XOR TABLE ab XOR --- --- --- TTF TFT FTT FFF a == !b TABLE ab !ba == !b --- --- --- ------- TTFF TFTT FTFT FFTF
certificate是,对input和输出的详尽研究表明,在两个表中,对于每个input集合,两个表格中的结果总是相同的。
所以,原来的问题是如何写:
return (A==5) ^^ (B==5)
答案是
return (A==5) == !(B==5);
或者,如果你喜欢,写
return !(A==5) == (B==5);
#if defined(__OBJC__) #define __bool BOOL #include <stdbool.h> #define __bool bool #endif static inline __bool xor(__bool a, __bool b) { return (!a && b) || (a && !b); }
它按照定义工作。 条件是检测是否使用Objective-C ,它是要求BOOL而不是bool(长度不同!)