¿Hay tal cosa? Es la primera vez que encuentro una necesidad práctica, pero no veo una lista en Stroustrup . Tengo la intención de escribir:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Pero no hay ^^
operador. ¿Puedo usar bitwise ^
aquí y obtener la respuesta correcta (independientemente de la representación de máquina de verdadero y falso)? Nunca mezclo &
y &&
, o |
y ||
, así que dudo en hacer eso con ^
y ^^
.
Me sentiría más cómodo escribiendo mi propia bool XOR(bool,bool)
función en su lugar.
Respuestas:
El
!=
operador cumple este propósito para losbool
valores.fuente
bool
valores" porque no necesariamente hace lo que puede desear para los no booleanos. Y como se trata de C ++, existe unbool
tipo real en lugar de tener que usarloint
para ese propósito.a
solo escribe!(a) != !(a)
Para una verdadera operación XOR lógica, esto funcionará:
Tenga en cuenta que
!
están allí para convertir los valores en booleanos y negarlos, de modo que dos enteros positivos desiguales (cada uno atrue
) se evaluaríanfalse
.fuente
!!
funcionaría solo preguntar bien, pero como necesitan ser diferentes, negarlos no hace daño.La implementación adecuada de XOR lógico manual depende de cuán estrechamente desee imitar el comportamiento general de otros operadores lógicos (
||
y&&
) con su XOR. Hay dos cosas importantes sobre estos operadores: 1) garantizan la evaluación de cortocircuito, 2) introducen un punto de secuencia, 3) evalúan sus operandos solo una vez.La evaluación XOR, como comprenderá, no se puede cortocircuitar ya que el resultado siempre depende de ambos operandos. Entonces 1 está fuera de cuestión. ¿Pero qué hay de 2? Si no le importan 2, entonces, con
bool
valores normalizados (es decir , el operador)!=
hace el trabajo de XOR en términos del resultado. Y los operandos se pueden normalizar fácilmente con unario!
, si es necesario. Por lo tanto,!A != !B
implementa el XOR adecuado en ese sentido.Pero si le importa el punto de secuencia adicional, ni la manera adecuada de implementar XOR es
!=
ni bit a bit^
. Una posible forma de hacer XOR (a, b) correctamente podría tener el siguiente aspectoEn realidad, esto es lo más cerca que puede llegar a hacer un XOR casero "similar" a
||
y&&
. Esto solo funcionará, por supuesto, si implementa su XOR como una macro. Una función no funcionará, ya que la secuencia no se aplicará a los argumentos de la función.Sin embargo, alguien podría decir que la única razón de tener un punto de secuencia en cada uno
&&
y||
es apoyar la evaluación de cortocircuito, y por lo tanto, XOR no necesita uno. Esto tiene sentido, en realidad. Sin embargo, vale la pena considerar tener un XOR con un punto de secuencia en el medio. Por ejemplo, la siguiente expresióntiene un comportamiento definido y un resultado específico en C / C ++ (con respecto a la secuencia al menos). Entonces, uno podría esperar razonablemente lo mismo de XOR lógico definido por el usuario , como en
mientras que un
!=
XOR basado en no tiene esta propiedad.fuente
||
y&&
: C) evalúan los operandos en un contexto booleano. Es decir,1 && 2
es cierto, a diferencia de lo1 & 2
que es cero. Del mismo modo, un^^
operador podría ser útil para proporcionar esta característica adicional, de evaluar los operandos en un contexto booleano. Por ejemplo,1 ^^ 2
es falso (a diferencia1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, una llamada comoint x = 2; XOR(++x > 1, x < 5);
dará el resultado incorrecto. La llamada tendría que tener paréntesis adicionales, como enint x = 2; XOR( (++x > 1), (x < 5) );
, con el fin de dar el resultado esperado correcta.Hay otra forma de hacer XOR:
Que obviamente se puede demostrar que funciona a través de:
fuente
El operador XOR no se puede cortocircuitar; es decir, no puede predecir el resultado de una expresión XOR simplemente evaluando su operando izquierdo. Por lo tanto, no hay razón para proporcionar una
^^
versión.fuente
&&
y&
en absoluto. Su punto es que no hay razón para presentar^^
. Sospecho que la propiedad que^^
consideraría cualquier valor no nulo1
no es realmente útil. O al menos no veo ningún uso.Hubo un buen código publicado que resolvió el problema mejor que! A! =! B
Tenga en cuenta que tuve que agregar BOOL_DETAIL_OPEN / CLOSE para que funcione en MSVC 2010
fuente
Use un simple:
fuente
Así es como creo que escribes una comparación XOR en C ++:
Prueba
La prueba es que un estudio exhaustivo de entradas y salidas muestra que en las dos tablas, para cada conjunto de entradas, el resultado es siempre el mismo en las dos tablas.
Por lo tanto, la pregunta original es cómo escribir:
La respuesta seria
O si quieres, escribe
fuente
(A || B) && !(A && B)
La primera parte es A OR B, que es el OR inclusivo; la segunda parte es, NO A Y B. Juntos, obtienes A o B, pero no tanto A como B.
Esto proporcionará el XOR probado en la tabla de verdad a continuación.
fuente
Uso "xor" (parece que es una palabra clave; en Code :: Blocks al menos se pone en negrita) así como puedes usar "y" en lugar de
&&
y "o" en lugar de||
.Sí, es bit a bit. Lo siento.
fuente
and
yxor
son macros de biblioteca estándar. No son de "algún lugar", son de <iso646.h>. Estas macros también están en C99 (no estoy seguro acerca de C89 / 90).xor
significa bit a bit XOR embargo, mientras queand
es lógico y.struct A { compl A() { } };
para definir un destructor, por ejemplo.Funciona como se define. Los condicionales son para detectar si está utilizando Objective-C , que solicita BOOL en lugar de bool (¡la longitud es diferente!)
fuente