Почему в C # нет условного XOR
оператора?
Пример:
true xor false = true
true xor true = false
false xor false = false
Почему в C # нет условного XOR
оператора?
Пример:
true xor false = true
true xor true = false
false xor false = false
& | ^
) и условные операторы ( && ||
). Но вы правы (конечно), есть логичный XOR ...
Ответы:
В C # условные операторы выполняют свой вторичный операнд только при необходимости .
Поскольку XOR по определению должен проверять оба значения, условная версия была бы глупой.
Примеры :
Логическое И: &
- каждый раз проверяет обе стороны.
Логическое ИЛИ: |
- каждый раз проверяйте обе стороны.
Условное И: &&
- проверяет только 2-ю сторону, если 1-я сторона истинна.
Условное ИЛИ: ||
- проверять только вторую сторону, если первая сторона ложна.
Вопрос немного устарел, но ...
Вот как должен работать этот оператор:
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
Как видите, несуществующие ^^
можно заменить существующими!=
!=
что это сработает.
AND
и , OR
но ничего , какXOR
. или, по крайней мере, мы не осознавали !=
:) @TheEvilGreebo
Есть логический оператор XOR: ^
Документация: операторы C # и оператор ^
^
при использовании с логическими операндами это логический оператор. "для операндов типа bool оператор ^ вычисляет тот же результат, что и оператор неравенства! =". Вы также можете выполнить побитовое xor целочисленные операнды с помощью ^
. C # - это не C.
В качестве пояснения, оператор ^ работает как с целочисленными типами, так и с bool.
См . Оператор ^ MSDN (Справочник по C #) :
Двоичные операторы ^ предопределены для целочисленных типов и bool. Для целочисленных типов ^ вычисляет побитовое исключающее ИЛИ своих операндов. Для операндов типа bool ^ вычисляет логическое исключающее ИЛИ своих операндов; то есть результат будет истинным тогда и только тогда, когда истинен ровно один из его операндов.
Возможно, документация изменилась с 2011 года, когда был задан этот вопрос.
^
и предшествует этому на пять лет. Я сомневаюсь, что что-то изменилось.
Как спросил Марк Л. Вот правильная версия:
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
Ссылка: Эксклюзивное ИЛИ
О да, это так.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
просто, как и байт). Это 100% определенное и безопасное управляемое поведение. CLR не является грубым; Впервые я увидел такое поведение при использовании Microsoft Pex.
Условного xor не существует, но вы можете использовать логический, потому что xor определен для логических значений, и все условные сравнения оцениваются как логические.
Итак, вы можете сказать что-то вроде:
if ( (a == b) ^ (c == d))
{
}
1
. Это малоизвестный факт. Вы можете оказаться в ситуации, когда xor двух логических значений, не являющихся ложными, по-прежнему не является ложным! Тем не менее, в этом конкретном коде оператор xor применяется только к значениям в [0,1], поэтому мой комментарий не применяется (полностью).
&
также уязвим.
&&
как если бы это была &
неправильная компиляция.
Хотя существует логический оператор xor ^
, нет условного оператора xor. Вы можете добиться условного xor двух значений A и B, используя следующее:
A ? (!B) : B
Парены не обязательны, но я добавил их для ясности.
Как указывает The Evil Greebo, это оценивает оба выражения, но xor не может быть сокращено, как and and or .
0101 ^ 0011
имеет значение 0110
.
Не существует такой вещи, как условное (короткое замыкание) XOR. Условные операторы имеют смысл только тогда, когда есть способ окончательно определить окончательный результат, глядя только на первый аргумент. Для XOR (и сложения) всегда требуется два аргумента, поэтому после первого аргумента невозможно выполнить короткое замыкание.
Если вы знаете, что A = true, тогда (A XOR B) =! B.
Если вы знаете, что A = false, тогда (A XOR B) = B.
В обоих случаях, если вы знаете A, но не B, то вы знаете недостаточно (A XOR B). Вы всегда должны запоминать значения как A, так и B, чтобы вычислить ответ. Буквально не существует варианта использования, при котором вы когда-либо могли бы разрешить XOR без обоих значений.
Имейте в виду, что 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
Но это не XOR.
На этот вопрос был дан эмоциональный ответ, но я столкнулся с другой ситуацией. Это правда, что в условном XOR нет необходимости. Также верно, что можно использовать оператор ^. Однако, если вам нужно только проверить состояние операндов «истина || ложь», то ^ может привести к проблемам. Например:
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!), И его на самом деле проще. Это сработает, и я абсолютно не понимаю, почему его ответ был отклонен ...
if
требует логического выражения, оно даже не будет компилироваться с int.
!=
работает заменитель?