Что-то подобное существует? Это первый раз, когда я столкнулся с практической потребностью в этом, но я не вижу в списке Страуструпа . Я намерен написать:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Но нет ^^
оператора. Могу ли я использовать побитовое ^
здесь и получить правильный ответ (независимо от машинного представления истинного и ложного)? Я никогда не смешиваю &
и / &&
или |
и ||
, поэтому я не решаюсь делать это с ^
и ^^
.
bool XOR(bool,bool)
Вместо этого мне было бы удобнее написать свою собственную функцию.
Ответы:
!=
Оператор этой цели служит дляbool
значений.источник
bool
значений», потому что это не обязательно делает то, что вы могли бы хотеть для небулевых. И поскольку это C ++, существует реальныйbool
тип, вместо того, чтобы использовать егоint
для этой цели.a
просто напишите!(a) != !(a)
Для истинной логической операции XOR это будет работать:
Обратите внимание, что
!
здесь есть для преобразования значений в булевы значения и их отрицания, так что два неравных положительных целых числа (каждое аtrue
) будут иметь значениеfalse
.источник
!!
будет работать, просто спросите хорошо, но так как они должны отличаться, отрицание их не вредит.Правильная ручная логическая реализация XOR зависит от того, насколько близко вы хотите имитировать общее поведение других логических операторов (
||
и&&
) с вашим XOR. В этих операторах есть две важные вещи: 1) они гарантируют оценку короткого замыкания, 2) они вводят точку последовательности, 3) они оценивают свои операнды только один раз.Оценка XOR, как вы понимаете, не может быть закорочена, так как результат всегда зависит от обоих операндов. Так что 1 не может быть и речи. Но как насчет 2? Если вас не волнует 2, то
bool
оператор нормализованных (то есть ) значений!=
выполняет работу XOR с точки зрения результата. И операнды могут быть легко нормализованы с одинарными!
, если это необходимо. Таким образом,!A != !B
реализуется надлежащий XOR в этом отношении.Но если вам небезразлична дополнительная точка последовательности, ни правильное , ни
!=
побитовое не^
является правильным способом реализации XOR. Один из возможных способов сделать XOR (a, b) правильно может выглядеть следующим образомНа самом деле это настолько близко, насколько вы можете сделать самодельный XOR "похожим" на
||
и&&
. Конечно, это будет работать, только если вы реализуете XOR как макрос. Функция не будет выполнять, так как последовательность не будет применяться к аргументам функции.Кто-то может сказать, однако, что единственная причина наличия точки последовательности в каждой
&&
и||
состоит в поддержке короткозамкнутой оценки, и, следовательно, XOR не нуждается в ней. Это имеет смысл, на самом деле. Тем не менее, стоит подумать о наличии XOR с точкой последовательности в середине. Например, следующее выражениеопределил поведение и конкретный результат в C / C ++ (по крайней мере, в отношении последовательности). Таким образом, можно ожидать того же от пользовательского логического XOR, что и в
в то время как
!=
XOR на основе этого свойства не имеет.источник
||
и&&
: C) они оценивают операнды в логическом контексте. То есть1 && 2
это правда, в отличие от1 & 2
которого равен нулю. Аналогичным образом,^^
оператор может быть полезен для предоставления этой дополнительной функции оценки операндов в логическом контексте. Например1 ^^ 2
, ложно (в отличие от1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, то вызов likeint x = 2; XOR(++x > 1, x < 5);
даст неправильный результат. Вызов должен иметь дополнительные скобки, как вint x = 2; XOR( (++x > 1), (x < 5) );
, чтобы дать правильный ожидаемый результат.Есть еще один способ сделать XOR:
Что, очевидно, может быть продемонстрировано, чтобы работать через:
источник
Оператор XOR не может быть замкнут накоротко; то есть вы не можете предсказать результат выражения XOR, просто оценив его левый операнд. Таким образом, нет причин предоставлять
^^
версию.источник
&&
и&
вообще. Дело в том, что нет причин для введения^^
. Я подозреваю, что свойство,^^
которое рассматривает любое ненулевое значение,1
не очень полезно. Или, по крайней мере, я не вижу никакой пользы.Был опубликован хороший код, который решил проблему лучше, чем! A! =! B
Обратите внимание, что мне пришлось добавить BOOL_DETAIL_OPEN / CLOSE, чтобы он работал на MSVC 2010
источник
Используйте простое:
источник
Вот как я думаю, что вы пишете сравнение XOR в C ++:
доказательство
Доказательством является то, что исчерпывающее изучение входов и выходов показывает, что в двух таблицах для каждого входного набора результат всегда одинаков в двух таблицах.
Поэтому оригинальный вопрос заключается в том, как написать:
Ответ будет
Или, если хотите, напишите
источник
(A || B) && !(A && B)
Первая часть - это A OR B, которая является включающим OR; вторая часть, а не A и B. Вместе вы получите A или B, но не оба A и B.
Это обеспечит доказательство XOR в таблице истинности ниже.
источник
Я использую «xor» (кажется, это ключевое слово; по крайней мере, в Code :: Blocks оно выделяется жирным шрифтом) так же, как вы можете использовать «и» вместо
&&
и «или» вместо||
.Да, это побитовое. Сожалею.
источник
and
иxor
это стандартные макросы библиотеки. Они не откуда-то, они из <iso646.h>. Эти макросы также есть в C99 (не уверен насчет C89 / 90).xor
означает побитового исключающего , хотя, в то время какand
это логично и.struct A { compl A() { } };
, например, определить деструктор.Это работает как определено. Условия должны определить, используете ли вы Objective-C , который запрашивает BOOL вместо bool (длина другая!)
источник