Почему С# не имеет условного оператора XOR
?
Пример:
true xor false = true
true xor true = false
false xor false = false
Почему С# не имеет условного оператора XOR
?
Пример:
true xor false = true
true xor true = false
false xor false = false
В С# условные операторы при необходимости выполняют только свой вторичный операнд.
Поскольку XOR должен по определению тестировать оба значения, условная версия будет глупой.
<сильные > Примеры:
Логическое И: &
- каждый раз проверяет обе стороны.
Логическое ИЛИ: |
- каждый раз проверяйте обе стороны.
Условное И: &&
- проверяет только 2-ю сторону, если первая сторона истинна.
Условное ИЛИ: ||
- проверять только вторую сторону, если первая сторона неверна.
Вопрос немного устарел, но...
Как работает этот оператор:
true xor false = true
true xor true = false
false xor false = false
Вот как работает оператор: = с типами bool:
(true != false) // true
(true != true) // false
(false != false) // false
Итак, как вы видите, более совершенный ^^
можно заменить существующим !=
Есть логический оператор XOR: ^
Документация: операторы С# и оператор ^
В качестве пояснения оператор ^ работает как с целочисленными типами, так и с типом bool.
См. MSDN ^ Оператор (Справочник по С#):
Двоичные операторы ^ предопределены для целочисленных типов и bool. Для целочисленных типов ^ вычисляет побитовое исключающее ИЛИ его операндов. Для операндов bool ^ вычисляет логический исключающий или его операндов; то есть результат равен true, если и только если точно один из его операндов равен true.
Возможно, документация изменилась с 2011 года, когда был задан этот вопрос.
Как задано 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
Ссылка: Эксклюзивный OR
О да, это так.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
Условный xor не существует, но вы можете использовать логический, потому что xor определен для булевых, и все условные сравнения оцениваются как booleans.
Итак, вы можете сказать что-то вроде:
if ( (a == b) ^ (c == d))
{
}
Хотя существует логический оператор xor ^
, не существует оператора условный xor. Вы можете добиться условного xor двух значений A и B, используя следующее:
A ? (!B) : B
Параны не нужны, но я добавил их для ясности.
Как указывает The Evil Greebo, это оценивает оба выражения, но xor не может быть коротко замкнутым, например и и или.
вы можете использовать:
a = b ^ c;
как в c/С++
true ^ false = true
true ^ true = false
false ^ false = false
Условного (короткозамкнутого) 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...
}
}
В этом примере, если влево установлено значение 10 (0xa), а справа установлено значение 5 (0x5), вводится ветвь "успех". Для этого (упрощенного, если глупо) примера, это приведет к ошибке, так как вы не должны поворачивать влево и вправо одновременно. То, что я собрал у вопросителя, заключается не в том, что он действительно хотел условного, а в простом способе выполнить true/false для значений, переданных в xor.
Макрос мог бы сделать трюк:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Не стесняйтесь ударить меня, если я не знаком: o)
Я прочитал jimreed ответ ниже, после того как я опубликовал это (плохой Yapdog!), и его на самом деле проще. Это сработает, и я совершенно не знаю, почему его ответ был отклонен...