346

そんなことありますか?実用的なニーズに遭遇したのは初めてですが、Stroustrupにリストされているものは見当たりません。私は書くつもりです:

// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);

しかし、^^演算子はありません。ここでビット単位を使用して^、正しい答えを得ることができますか(trueとfalseのマシン表現に関係なく)?&&&、またはとを混ぜることは決してないので、|||でそれを行うことを躊躇し^ます^^

bool XOR(bool,bool)代わりに、独自の関数を作成する方が快適です。

4

11 に答える 11

629

演算子は、値に対して!=この目的を果たしboolます。

于 2009-10-20T19:03:38.340 に答える
287

真の論理XOR演算の場合、これは機能します。

if(!A != !B) {
    // code here
}

値をブール値に変換して否定するために存在することに注意してください!。これにより、2つの等しくない正の整数(それぞれa true)がに評価されfalseます。

于 2009-10-20T20:04:41.343 に答える
48

適切な手動論理||XORの実装は、他の論理演算子(および)の一般的な動作をXORでどれだけ模倣するかによって異なり&&ます。これらの演算子には2つの重要な点があります。1)短絡評価を保証する、2)シーケンスポイントを導入する、3)オペランドを1回だけ評価する。

ご存知のように、XOR評価は、結果が常に両方のオペランドに依存するため、短絡することはできません。したがって、1は問題外です。しかし、2はどうですか?2を気にしない場合は、正規化された(つまりbool)値を使用して、演算子!=が結果の観点からXORの役割を果たします。また、必要に応じて、オペランドを単項で簡単に正規化できます!。したがって!A != !B、その点で適切なXORを実装します。

ただし、余分なシーケンスポイントを気にする場合は、XORを実装する適切な方法は!=ビット単位でもありません。^XOR(a、b)を正しく実行するための1つの可能な方法は、次のようになります。

a ? !b : b

||これは、実際には、自家製のXORをおよびに「類似」させることができる限り近いものです&&。もちろん、これはXORをマクロとして実装する場合にのみ機能します。シーケンスは関数の引数に適用されないため、関数は機能しません。

&&ただし、それぞれにシーケンスポイントがあり、||短絡評価をサポートすることが唯一の理由であると言う人もいるかもしれません。したがって、XORにはシーケンスポイントは必要ありません。実際、これは理にかなっています。それでも、中央にシーケンスポイントを持つXORを使用することを検討する価値があります。たとえば、次の式

++x > 1 && x < 5

C / C ++での動作と特定の結果を定義しました(少なくともシーケンスに関して)。したがって、ユーザー定義の論理XORには、次のように同じことが合理的に期待できます。

XOR(++x > 1, x < 5)

一方、!=ベースのXORにはこのプロパティがありません。

于 2009-10-20T19:16:28.687 に答える
26

XORを実行する別の方法があります。

bool XOR(bool a, bool b)
{
    return (a + b) % 2;
}

これは明らかに、次の方法で機能することを示すことができます。

#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;
}
于 2012-10-07T12:17:38.610 に答える
17

XOR演算子を短絡させることはできません。つまり、左側のオペランドを評価するだけでは、XOR式の結果を予測することはできません。したがって、^^バージョンを提供する理由はありません。

于 2009-10-20T19:02:53.973 に答える
12

!a!=!bよりも問題を解決する優れたコードが投稿されました

MSVC 2010で機能するように、BOOL_DETAIL_OPEN/CLOSEを追加する必要があることに注意してください

/* 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
于 2012-09-06T02:46:47.877 に答える
5

単純なものを使用します。

return ((op1 ? 1 : 0) ^ (op2 ? 1 : 0));
于 2015-07-29T08:33:01.970 に答える
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
}

証拠

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

証明は、入力と出力の徹底的な調査により、2つのテーブルで、すべての入力セットについて、結果が2つのテーブルで常に同じであることが示されていることです。

したがって、元の質問はどのように書くかです:

return (A==5) ^^ (B==5)

答えは

return (A==5) == !(B==5);

または、必要に応じて、

return !(A==5) == (B==5);
于 2016-09-13T15:00:50.623 に答える
5

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

最初の部分はAORBで、これは包括的ORです。2番目の部分は、AとBではありません。一緒にAまたはBを取得しますが、AとBの両方を取得することはできません。

これにより、以下の真理値表で証明されたXORが提供されます。

|-----|-----|-----------|
|  A  |  B  |  A XOR B  |
|-----|-----|-----------|
|  T  |  T  |   False   |
|-----|-----|-----------|
|  T  |  F  |   True    |
|-----|-----|-----------|
|  F  |  T  |   True    |
|-----|-----|-----------|
|  F  |  F  |   False   |
|-----|-----|-----------|
于 2018-01-28T00:58:20.277 に答える
0

「xor」(キーワードのようです。Code :: Blocksでは少なくとも太字になります)を使用します。これは、の代わりに「and」を使用し、の代わりに&&「or」を使用できるのと同じです||

if (first xor second)...

はい、ビット単位です。ごめん。

于 2009-10-20T19:36:07.883 に答える
-1
#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);
}

定義どおりに機能します。条件は、boolの代わりにBOOLを要求しているObjective-Cを使用しているかどうかを検出することです(長さが異なります!)

于 2013-05-18T10:49:33.000 に答える