Por que C # não tem um XOR
operador condicional ?
Exemplo:
true xor false = true
true xor true = false
false xor false = false
Por que C # não tem um XOR
operador condicional ?
Exemplo:
true xor false = true
true xor true = false
false xor false = false
& | ^
) versus operadores condicionais ( && ||
). Mas você está certo (é claro), há um XOR lógico ...
Respostas:
Em C #, os operadores condicionais apenas executam seu operando secundário se necessário .
Visto que um XOR deve, por definição, testar ambos os valores, uma versão condicional seria boba.
Exemplos :
E lógico: &
- testa ambos os lados sempre.
OR lógico: |
- teste ambos os lados sempre.
E condicional: &&
- testa apenas o 2º lado se o 1º lado for verdadeiro.
OU condicional: ||
- teste apenas o 2º lado se o 1º lado for falso.
A pergunta está um pouco desatualizada, mas ...
É assim que esse operador deve funcionar:
true xor false = true
true xor true = false
false xor true = true
false xor false = false
É assim que o operador! = Funciona com tipos bool:
(true != false) // true
(true != true) // false
(false != true) // true
(false != false) // false
Como você vê, o inexistente ^^
pode ser substituído pelo existente!=
!=
que funcionaria para isso.
AND
e OR
nada como XOR
. ou pelo menos não percebemos !=
:) @TheEvilGreebo
Existe o operador lógico XOR: ^
Documentação: Operadores C # e Operador ^
^
, quando usado com operandos booleanos, é um operador booleano. "para os operandos bool, o operador ^ calcula o mesmo resultado que o operador desigualdade! =". Você também pode bit a bit x ou operandos inteiros com ^
. C # não é C.
Apenas para esclarecimento, o operador ^ funciona com tipos integrais e bool.
Consulte o Operador ^ do MSDN (referência C #) :
Operadores binários ^ são predefinidos para os tipos integrais e bool. Para tipos integrais, ^ calcula o OR exclusivo bit a bit de seus operandos. Para operandos bool, ^ calcula o exclusivo-or lógico de seus operandos; ou seja, o resultado é verdadeiro se e somente se exatamente um de seus operandos for verdadeiro.
Talvez a documentação tenha mudado desde 2011, quando essa pergunta foi feita.
^
e antecede esta em cinco anos. Duvido que algo tenha mudado.
Conforme solicitado por Mark L , aqui está a versão correta:
Func<bool, bool, bool> XOR = (X,Y) => ((!X) && Y) || (X && (!Y));
Aqui está a tabela verdade:
X | Y | Result
==============
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
Referência: OU exclusivo
Oh sim, é verdade.
bool b1 = true;
bool b2 = false;
bool XOR = b1 ^ b2;
i1
, assim como um byte). Este é um comportamento 100% definido e gerenciado de forma segura. O CLR não é maltratado .; A primeira vez que vi esse comportamento foi ao usar o Microsoft Pex.
O xor condicional não existe, mas você pode usar um lógico porque xor é definido para booleanos e todas as comparações condicionais são avaliadas como booleanos.
Então você pode dizer algo como:
if ( (a == b) ^ (c == d))
{
}
1
. Este é um fato pouco conhecido. Você pode acabar em uma situação onde o xor de dois booleanos não falsos ainda é não falso! Dito isso, neste código em particular, o operador xor só é aplicado a valores em [0,1], de modo que meu comentário não se aplica (totalmente).
&
também é vulnerável.
&&
como se fosse &
uma compilação incorreta.
Embora haja um operador xor lógico^
, não há operador xor condicional . Você pode obter um xor condicional de dois valores A e B usando o seguinte:
A ? (!B) : B
Os parênteses não são necessários, mas eu os adicionei para maior clareza.
Como apontado por The Evil Greebo, isso avalia ambas as expressões, mas xor não pode ser curto-circuitado como e e ou .
0101 ^ 0011
tem o valor 0110
.
Não existe XOR condicional (curto-circuito). Os operadores condicionais só são significativos quando há uma maneira de determinar definitivamente o resultado final olhando apenas para o primeiro argumento. XOR (e adição) sempre requerem dois argumentos, portanto, não há como entrar em curto-circuito após o primeiro argumento.
Se você souber A = verdadeiro, então (A XOR B) =! B.
Se você souber A = falso, então (A XOR B) = B.
Em ambos os casos, se você conhece A, mas não B, então não sabe o suficiente para saber (A XOR B). Você deve sempre aprender os valores de A e B para calcular a resposta. Não existe literalmente nenhum caso de uso em que você possa resolver o XOR sem os dois valores.
Lembre-se de que o XOR, por definição, tem quatro casos:
false xor true = true
true xor false = true
true xor true = false
false xor false = false
Mais uma vez, espero que seja óbvio pelo que foi dito acima que saber o primeiro valor nunca é suficiente para obter a resposta sem também saber o segundo valor. No entanto, em sua pergunta, você omitiu o primeiro caso. Se você ao invés quisesse
false op true = false (or DontCare)
true op false = true
true op true = false
false op false = false
então você pode realmente conseguir isso por uma operação condicional de curto-circuito:
A && !B
Mas isso não é um XOR.
Essa pergunta foi respondida afetivamente, mas me deparei com uma situação diferente. É verdade que não há necessidade de um XOR condicional. Também é verdade que o operador ^ pode ser usado. No entanto, se você precisar apenas testar o status "verdadeiro || falso" dos operandos, ^ pode causar problemas. Por exemplo:
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...
}
}
Neste exemplo, se a esquerda for definida como 10 (0xa) e a direita como 5 (0x5), o desvio "sucesso" é inserido. Para este exemplo (simplista, se bobo), isso resultaria em um bug, já que você não deve virar à esquerda E à direita ao mesmo tempo. O que deduzi do questionador não é que ele realmente queria uma condicional, mas uma maneira simples de executar verdadeiro / falso nos valores passados para xor.
Uma macro pode resolver o problema:
#define my_xor(a, b) ( ((a)?1:0) ^ ((b)?1:0) )
Sinta-se à vontade para me dar um tapa se eu errar o alvo: o)
Eu li a resposta de Jimreed abaixo depois de postar isso (Yapdog ruim!) E a dele é realmente mais simples. Funcionaria e eu não tenho absolutamente nenhuma ideia de por que sua resposta foi rejeitada ...
if
requer uma expressão booleana, nem mesmo é compilada com um int.
!=
funciona como substituto?