¿Operador lógico XOR en C++?
¿existe tal cosa? Es la primera vez que encuentro una necesidad práctica para ello, 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 un operador ^^
. ¿Puedo usar el bitwise ^
aquí y obtener la respuesta correcta (independientemente de la representación de la máquina de verdadero y falso)? Nunca mezclo &
y &&
, o |
y ||
, así que dudo en hacer eso con ^
y ^^
.
Estaría más cómodo escribiendo mi propia función bool XOR(bool,bool)
en su lugar.
11 answers
El operador !=
sirve para este propósito para los valores bool
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-20 19:03:38
Para una verdadera operación lógica XOR, esto funcionará:
if(!A != !B) {
// code here
}
La razón por la que negamos A
y B
es para convertirlos a booleanos. La negación no es la intención. Un truco común para convertir enteros a booleanos es usar !!
. Esto convertirá el valor de una variable a 0
si la variable era 0
y 1
de lo contrario. Podríamos haber usado !!A != !!B
en su lugar. Otra forma de hacerlo es usar (_Bool)A != (_Bool)B
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-10 00:38:13
Manual apropiado lógico La implementación de XOR depende de qué tan cerca se desea imitar el comportamiento general de otros operadores lógicos (||
y &&
) con su XOR. Hay dos cosas importantes acerca de 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 usted entiende, no puede ser cortocircuitada ya que el resultado siempre depende de ambos operandos. Así que 1 está fuera de pregunta. ¿Pero qué pasa con 2? Si no le importa 2, entonces con valores normalizados (es decir, bool
) el operador !=
hace el trabajo de XOR en términos del resultado. Y los operandos pueden ser fácilmente normalizados con unary !
, si es necesario. Así !A != !B
implementa el XOR apropiado en ese sentido.
Pero si te importa el punto de secuencia adicional, sin embargo, ni !=
ni bitwise ^
es la forma correcta de implementar XOR. Una forma posible de hacer XOR (a, b) correctamente podría verse como sigue
a ? !b : b
Esto es en realidad lo más cercano que puedes 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 secuenciación no se aplicará a los argumentos de la función.
Alguien podría decir, sin embargo, que la única razón de tener un punto de secuencia en cada &&
y ||
es para apoyar la evaluación en cortocircuito, y por lo tanto XOR no necesita uno. Esto tiene sentido, en realidad. Aun, vale la pena considerar tener un XOR con un punto de secuencia en el medio. Por ejemplo, la siguiente expresión
++x > 1 && x < 5
Tiene un comportamiento definido y un resultado específico en C/C++ (con respecto a la secuenciación al menos). Por lo tanto, uno podría esperar razonablemente lo mismo de lógico XOR definido por el usuario, como en
XOR(++x > 1, x < 5)
Mientras que un XOR basado en !=
no tiene esta propiedad.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 17:35:12
Hay otra manera de hacer XOR:
bool XOR(bool a, bool b)
{
return (a + b) % 2;
}
Que obviamente se puede demostrar que funciona a través de:
#include <iostream>
bool XOR(bool a, bool b)
{
return (a + b) % 2;
}
int main()
{
using namespace std;
cout << "XOR(true, true):\t" << XOR(true, true) << endl
<< "XOR(true, false):\t" << XOR(true, false) << endl
<< "XOR(false, true):\t" << XOR(false, true) << endl
<< "XOR(false, false):\t" << XOR(false, false) << endl
<< "XOR(0, 0):\t\t" << XOR(0, 0) << endl
<< "XOR(1, 0):\t\t" << XOR(1, 0) << endl
<< "XOR(5, 0):\t\t" << XOR(5, 0) << endl
<< "XOR(20, 0):\t\t" << XOR(20, 0) << endl
<< "XOR(6, 6):\t\t" << XOR(5, 5) << endl
<< "XOR(5, 6):\t\t" << XOR(5, 6) << endl
<< "XOR(1, 1):\t\t" << XOR(1, 1) << endl;
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-12 15:08:54
El operador XOR no puede ser cortocircuitado; es decir, no se puede predecir el resultado de una expresión XOR simplemente evaluando su operando de la mano izquierda. Por lo tanto, no hay razón para proporcionar una versión ^^
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-20 19:02:53
Hubo un buen código publicado que resolvió el problema mejor que !¡a != !b
Tenga en cuenta que tuve que agregar el BOOL_DETAIL_OPEN / CLOSE para que funcionara en MSVC 2010
/* From: http://groups.google.com/group/comp.std.c++/msg/2ff60fa87e8b6aeb
Proposed code left-to-right? sequence point? bool args? bool result? ICE result? Singular 'b'?
-------------- -------------- --------------- ---------- ------------ ----------- -------------
a ^ b no no no no yes yes
a != b no no no no yes yes
(!a)!=(!b) no no no no yes yes
my_xor_func(a,b) no no yes yes no yes
a ? !b : b yes yes no no yes no
a ? !b : !!b yes yes no no yes no
[* see below] yes yes yes yes yes no
(( a bool_xor b )) yes yes yes yes yes yes
[* = a ? !static_cast<bool>(b) : static_cast<bool>(b)]
But what is this funny "(( a bool_xor b ))"? Well, you can create some
macros that allow you such a strange syntax. Note that the
double-brackets are part of the syntax and cannot be removed! The set of
three macros (plus two internal helper macros) also provides bool_and
and bool_or. That given, what is it good for? We have && and || already,
why do we need such a stupid syntax? Well, && and || can't guarantee
that the arguments are converted to bool and that you get a bool result.
Think "operator overloads". Here's how the macros look like:
Note: BOOL_DETAIL_OPEN/CLOSE added to make it work on MSVC 2010
*/
#define BOOL_DETAIL_AND_HELPER(x) static_cast<bool>(x):false
#define BOOL_DETAIL_XOR_HELPER(x) !static_cast<bool>(x):static_cast<bool>(x)
#define BOOL_DETAIL_OPEN (
#define BOOL_DETAIL_CLOSE )
#define bool_and BOOL_DETAIL_CLOSE ? BOOL_DETAIL_AND_HELPER BOOL_DETAIL_OPEN
#define bool_or BOOL_DETAIL_CLOSE ? true:static_cast<bool> BOOL_DETAIL_OPEN
#define bool_xor BOOL_DETAIL_CLOSE ? BOOL_DETAIL_XOR_HELPER BOOL_DETAIL_OPEN
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-06 03:06:02
Utilice un simple:
return ((op1 ? 1 : 0) ^ (op2 ? 1 : 0));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-18 20:55:11
Así es como creo que escribes una comparación XOR en C++:
bool a = true; // Test by changing to true or false
bool b = false; // Test by changing to true or false
if (a == !b) // THIS IS YOUR XOR comparison
{
// do whatever
}
Prueba
XOR TABLE
a b XOR
--- --- ---
T T F
T F T
F T T
F F F
a == !b TABLE
a b !b a == !b
--- --- --- -------
T T F F
T F T T
F T F T
F F T F
La prueba es que un estudio exhaustivo de entradas y salidas muestra que en las dos tablas, para cada conjunto de entrada el resultado es siempre el mismo en las dos tablas.
Por lo tanto, la pregunta original es cómo escribir:
return (A==5) ^^ (B==5)
, La respuesta sería
return (A==5) == !(B==5);
O si quieres, escribe
return !(A==5) == (B==5);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-13 15:00:50
(A || B) && !(A && B)
La primera parte es A O B, que es el OR Inclusivo; la segunda parte ES, NO A Y B. Juntos obtienes A o B, pero no ambos A y B.
Esto proporcionará el XOR demostrado en la tabla de verdad a continuación.
|-----|-----|-----------|
| A | B | A XOR B |
|-----|-----|-----------|
| T | T | False |
|-----|-----|-----------|
| T | F | True |
|-----|-----|-----------|
| F | T | True |
|-----|-----|-----------|
| F | F | False |
|-----|-----|-----------|
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-28 00:58:20
Uso "xor" (parece que es una palabra clave; en Code::Blocks al menos se pone en negrita) así como puedes usar "and" en lugar de &&
y "or" en lugar de ||
.
if (first xor second)...
Sí, es bit a bit. Disculpe....
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-18 20:52:30
#if defined(__OBJC__)
#define __bool BOOL
#include <stdbool.h>
#define __bool bool
#endif
static inline __bool xor(__bool a, __bool b)
{
return (!a && b) || (a && !b);
}
Funciona como se define. Los condicionales son para detectar si está utilizando Objective-C, que está pidiendo BOOL en lugar de bool (la longitud es diferente!)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-12 15:09:54