Existe uma coisa dessas? É a primeira vez que encontrei uma necessidade prática, mas não vejo uma listada no Stroustrup . Eu pretendo escrever:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Mas não há ^^
operador. Posso usar o bit a bit ^
aqui e obter a resposta certa (independentemente da representação da máquina como verdadeira e falsa)? Eu nunca misturo &
e &&
, ou |
e ||
, por isso hesito em fazer isso com ^
e ^^
.
Eu ficaria mais confortável escrevendo minha própria bool XOR(bool,bool)
função.
Respostas:
O
!=
operador serve a esse propósito parabool
valores.fonte
bool
valores" porque não faz necessariamente o que você pode querer para não-booleanos. E como esse é o C ++, existe umbool
tipo real em vez de ser necessárioint
para esse fim.a
apenas escrever!(a) != !(a)
Para uma verdadeira operação lógica do XOR, isso funcionará:
Observe que
!
existem para converter os valores em booleanos e negá-los, para que dois inteiros positivos desiguais (cada umtrue
) sejam avaliados comofalse
.fonte
!!
funcionaria apenas pedir bem, mas como eles precisam ser diferentes, negá-los não faz mal.A implementação manual correta do XOR lógico depende de quão próximo você deseja imitar o comportamento geral de outros operadores lógicos (
||
e&&
) com o seu XOR. Há duas coisas importantes sobre esses operadores: 1) garantem a avaliação de curto-circuito, 2) introduzem um ponto de sequência, 3) avaliam seus operandos apenas uma vez.A avaliação do XOR, como você entende, não pode ter um curto-circuito, pois o resultado sempre depende dos dois operandos. Então, 1 está fora de questão. Mas e quanto a 2? Se você não se importa com 2, o
bool
operador com valores normalizados (ou seja )!=
realiza o trabalho de XOR em termos do resultado. E os operandos podem ser facilmente normalizados com unário!
, se necessário. Assim,!A != !B
implementa o XOR apropriado a esse respeito.Mas se você se importa com o ponto extra de sequência,
!=
nem a bit^
a bit é a maneira correta de implementar o XOR. Uma maneira possível de executar o XOR (a, b) corretamente pode ser a seguinteEste é realmente o mais perto que você pode começar a fazer um XOR caseiro "similar" à
||
e&&
. Obviamente, isso só funcionará se você implementar seu XOR como uma macro. Uma função não funciona, pois o seqüenciamento não se aplica aos argumentos da função.Alguém pode dizer, porém, que a única razão de ter um ponto de sequência em cada um
&&
e||
é apoiar a avaliação em curto-circuito e, portanto, o XOR não precisa de um. Isso faz sentido, na verdade. No entanto, vale a pena considerar ter um XOR com um ponto de sequência no meio. Por exemplo, a seguinte expressãodefiniu comportamento e resultado específico em C / C ++ (com relação ao seqüenciamento, pelo menos). Portanto, pode-se esperar razoavelmente o mesmo do XOR lógico definido pelo usuário , como em
enquanto um
!=
XOR baseado em não tem essa propriedade.fonte
||
e&&
: C) eles avaliam os operandos em um contexto booleano. Ou seja,1 && 2
é verdade, ao contrário de1 & 2
zero. Da mesma forma, um^^
operador pode ser útil para fornecer esse recurso extra, para avaliar os operandos em um contexto booleano. Por exemplo,1 ^^ 2
é falso (diferente1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, uma chamada comoint x = 2; XOR(++x > 1, x < 5);
dará o resultado errado. A chamada teria que ter parênteses extras, como emint x = 2; XOR( (++x > 1), (x < 5) );
, para fornecer o resultado esperado correto.Há outra maneira de fazer o XOR:
O que obviamente pode ser demonstrado para funcionar através de:
fonte
O operador XOR não pode ter um curto-circuito; ou seja, você não pode prever o resultado de uma expressão XOR apenas avaliando seu operando esquerdo. Portanto, não há razão para fornecer uma
^^
versão.fonte
&&
e&
em tudo. Seu argumento é que não há razão para apresentar^^
. A propriedade que^^
consideraria qualquer valor não nulo como1
não é realmente útil, eu suspeito. Ou pelo menos não consigo ver nenhum uso.Houve um bom código postado que resolveu o problema melhor do que! A! =! B
Observe que eu tive que adicionar o BOOL_DETAIL_OPEN / CLOSE para que ele funcionasse no MSVC 2010
fonte
Use um simples:
fonte
Aqui está como eu acho que você escreve uma comparação XOR em C ++:
Prova
A prova é que um estudo exaustivo de entradas e saídas mostra que, nas duas tabelas, para cada conjunto de entradas, o resultado é sempre o mesmo nas duas tabelas.
Portanto, a pergunta original é como escrever:
A resposta seria
Ou, se quiser, escreva
fonte
(A || B) && !(A && B)
A primeira parte é A OR B, que é o OR Inclusivo; a segunda parte é, NÃO A e B. Juntos, você obtém A ou B, mas não ambos, A e B.
Isso fornecerá o XOR comprovado na tabela verdade abaixo.
fonte
Eu uso "xor" (parece que é uma palavra-chave; em Code :: Blocks, pelo menos, fica em negrito), assim como você pode usar "e" em vez de
&&
e "ou" em vez de||
.Sim, é bit a bit. Desculpe.
fonte
and
exor
são macros de biblioteca padrão. Eles não são de "algum lugar", eles são de <iso646.h>. Essas macros também estão no C99 (não tenho certeza sobre o C89 / 90).xor
significa bit a bit xor, emboraand
seja lógico e.struct A { compl A() { } };
definir um destruidor, por exemplo.Funciona como definido. Os condicionais são para detectar se você está usando Objective-C , que está pedindo BOOL em vez de bool (o comprimento é diferente!)
fonte