95

为什么 C# 没有条件XOR运算符?

例子:

true  xor false = true
true  xor true  = false
false xor false = false
4

11 回答 11

310

条件异或应该像这样工作:

true xor false = true
true xor true = false
false xor true = true
false xor false = false

但这就是!=操作符实际使用 bool 类型的方式:

(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false

如您所见,不存在的^^可以替换为存在的!=

于 2013-02-02T18:02:05.877 回答
130

在 C# 中,条件运算符仅在必要时执行其辅助操作数。

由于 XOR必须根据定义测试两个值,因此条件版本将是愚蠢的。

例子

  • 逻辑与:&- 每次都测试双方。

  • 逻辑或:|- 每次都测试双方。

  • 条件与:&&- 如果第一面为真,则仅测试第二面。

  • 条件或:||- 如果第一面为假,则仅测试第二面。

于 2011-06-28T14:17:36.140 回答
30

有逻辑 XOR 运算符:^

文档:C# 运算符^ 运算符

文档明确指出^,当与布尔操作数一起使用时,它是一个布尔运算符。

"对于 bool 操作数,^ 运算符计算的结果与不等式运算符 !=" 相同。

(正如另一个答案中所述,这正是您想要的)。

您还可以使用 ^ 对整数操作数进行按位异或。

于 2011-06-28T14:15:00.127 回答
25

澄清一下,^ 运算符适用于整数类型和 bool。

请参阅MSDN 的 ^ 运算符(C# 参考)

二进制 ^ 运算符是为整数类型和 bool 预定义的。对于整数类型,^ 计算其操作数的按位异或。对于 bool 操作数,^ 计算其操作数的逻辑异或;也就是说,当且仅当其操作数之一为真时,结果才为真。

自 2011 年提出此问题以来,文档可能已更改。

于 2016-06-13T11:50:47.507 回答
13

正如Mark L所问,这是正确的版本:

 Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));

这是真值表:

 X | Y | Result
 ==============
 0 | 0 | 0
 1 | 0 | 1
 0 | 1 | 1
 1 | 1 | 0

参考: 异或

于 2015-12-29T11:04:01.353 回答
5

哦,是的,确实如此。

bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
于 2011-06-28T14:15:29.743 回答
4

条件异或不存在,但您可以使用逻辑异或,因为异或是为布尔值定义的,并且所有条件比较都计算为布尔值。

所以你可以这样说:

if ( (a == b) ^ (c == d))
{

}
于 2011-06-28T14:19:51.040 回答
3

虽然有逻辑异或运算符^,但没有条件异或运算符。您可以使用以下方法实现两个值 A 和 B 的条件异或:

A ? (!B) : B

括号不是必需的,但为了清楚起见,我添加了它们。

正如 The Evil Greebo 所指出的,这会计算两个表达式,但 xor 不能像andor那样短路。

于 2011-06-28T14:21:41.120 回答
1

您可以使用:

a = b ^ c;

就像在 c/c++ 中一样

于 2011-06-28T14:16:09.470 回答
0

没有条件(短路)异或之类的东西。仅当有一种方法可以通过仅查看第一个参数来明确判断最终结果时,条件运算符才有意义。XOR(和加法)总是需要两个参数,所以在第一个参数之后没有办法短路。

如果您知道 A=true,那么 (A XOR B) = !B。

如果你知道 A=false,那么 (A XOR B) = B。

在这两种情况下,如果你知道 A 但不知道 B,那么你知道的还不够多(A XOR B)。为了计算答案,您必须始终学习 A 和 B 的值。从字面上看,没有任何用例可以在没有两个值的情况下解决 XOR。

请记住,根据定义,异或有四种情况:

false xor true  = true
true  xor false = true
true  xor true  = false
false xor false = false

同样,希望从上面很明显,知道第一个值永远不足以在不知道第二个值的情况下得到答案。但是,在您的问题中,您省略了第一种情况。如果你想要

false op true  = false (or DontCare)
true  op false = true
true  op true  = false
false op false = false

那么您确实可以通过短路条件操作来获得它:

A && !B

但这不是异或。

于 2019-05-15T21:29:16.203 回答
-3

这个问题已经得到了有效的回答,但我遇到了不同的情况。确实不需要条件异或。也可以使用 ^ 运算符。但是,如果您只需要测试操作数的“true || false”状态,那么 ^ 可能会导致麻烦。例如:

void Turn(int left, int right)
{
    if (left ^ right)
    {
        //success... turn the car left or right...
    }
    else
    {
        //error... no turn or both left AND right are set...
    }
}

在本例中,如果 left 设置为 10 (0xa),right 设置为 5 (0x5),则进入“成功”分支。对于这个(如果很愚蠢的话很简单)的例子,这会导致一个错误,因为你不应该同时左转和右转。我从提问者那里收集到的并不是他实际上想要一个条件,而是一种简单的方法来对传递给 xor 的值执行真/假。

宏可以解决问题:

#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )

如果我不合时宜,请随意扇我一巴掌:o)

在我发布这个(糟糕的 Yapdog!)之后,我在下面阅读了 jimreed 的答案,而他的答案实际上更简单。它会起作用,我完全不知道为什么他的回答被否决了......

于 2012-08-20T23:08:01.537 回答