Me deparei com o seguinte trecho de código
if( 0 != ( x ^ 0x1 ) )
encode( x, m );
O que x ^ 0x1
significa isso ? Isso é alguma técnica padrão?
c++
c
bit-manipulation
bitmask
KodeWarrior
fonte
fonte
0 != (x ^ 1)
→ xou ambos os lados por 1 →(0 ^ 1) != (x ^ 1 ^ 1)
→ simplificar →1 != x
if (1 != x)
é difícil escrever.type
dex
não é fornecido - portanto, não sabemos que esse é um número inteiro nesse problema marcado com C ++. Claro, se este é C oux
é um número inteiro, a resposta é fácil, mas isso não é um dado eoperator ^
existe a possibilidade de sobrecarga .Respostas:
A operação XOR (
x ^ 0x1
) inverte o bit 0. Portanto, a expressão significa efetivamente: se o bit 0 de x é 0 ou qualquer outro bit de x é 1, a expressão é verdadeira.Por outro lado, a expressão é falsa se x == 1.
Portanto, o teste é o mesmo que:
e é, portanto, (sem dúvida) desnecessariamente ofuscado.
fonte
^
é o bit a bit XOR operação0x1
está1
em notação hexadecimalx ^ 0x1
irá inverter o último bit dex
(consulte a tabela verdade do XOR no link acima, se isso não estiver claro para você).Portanto, a condição
(0 != ( x ^ 0x1 ))
será verdadeira sex
for maior que 1 ou se o último bitx
for 0. O que deixa apenas x == 1 como um valor no qual a condição será falsa. Então é equivalente aPS Inferno de uma maneira de implementar uma condição tão simples, devo acrescentar. Não faça isso. E se você precisar escrever um código complicado, deixe um comentário . Eu imploro a você.
fonte
x==0
;4 ^ 0x1
é verdade, mas4==0
é obviamente falsa.if (x == 0)
", não é igual ax != 1
?x
é um tipo integral. Se é umfloat
oudouble
, então acredito que a expressão renderia verdadeira para1.0 <= x < 2.0
. E sex
for do tipo definido pelo usuário, a expressão poderá retornar verdadeira sex
for um yugo, canguru, aniversário do famoso compositor ou qualquer número que compartilhe pelo menos três dígitos com o preço atual do chá em dólar na China.operator^
parafloat
/double
.Isso pode parecer uma explicação simplificada, mas se alguém quiser passar por isso lentamente, está abaixo:
^
é um operador XOR bit a bit em c, c ++ e c #.A tabela verdade de a xor b :
Então, vamos ilustrar a
0 == ( x ^ 0x1 )
expressão no nível binário:tão:
fonte
É um operador exclusivo OR (XOR). Para entender como funciona, você pode executar este código simples
A saída será
Então essa expressão
será igual a verdade somente quando x! = 0x1.
Não muda x em si. Ele verifica apenas se x é igual a 0 ou 1. essa expressão pode ser alterada para
fonte
Ele verifica que
x
na verdade não é0x1
...xor
ingx
com0x1
resultará em 0 somente sex
é0x1
... este é um velho truque usado principalmente em linguagem assemblyfonte
!= 1
?xor
abordagem continha menos código de máquina e foi executada mais rapidamente do que a atribuição correspondente a0
... no entanto, esta pergunta contém umaxor
comparação AND, por isso acho que!=
pode ser Mais rápido. Não tenho tanta certeza, no entanto, precisaria ver algum assembly gerado pelo compilador.O
^
operador é bit a bit xor. E0x1
é o número1
, escrito como uma constante hexadecimal.Portanto,
x ^ 0x1
avalia um novo valor que é igual ax
, mas com o bit menos significativo invertido.O código nada mais faz do que comparar x com 1, de uma maneira muito complicada e obscura.
fonte
O operador xor (exclusivo ou) é mais comumente usado para inverter um ou mais bits. A operação é perguntar se exatamente um dos bits é um, isso leva à seguinte tabela verdade (A e B são entradas, Y é saída):
Agora, o objetivo deste código parece ser verificar exatamente se o último bit é 1 e os outros são 0, isso é igual
if ( x != 1 )
. A razão para esse método obscuro pode ser que técnicas de manipulação de bits anteriores foram usadas e talvez sejam usadas em outros locais do programa.fonte
^
é bit a bitxor operator
emc
. No seu caso, x é xado com 1. por exemplo,x
tem o valor 10, então10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
a condição se torna verdadeira.fonte
10 != 1010
10 (decimal) == 1010 (binary)
b
ou algo lá?O teste bit a bit parece ser uma ofuscação deliberada, mas se os dados subjacentes são dados corporativos de um sistema de mainframe IBM, pode ser que simplesmente o código tenha sido escrito para refletir a documentação original. Os formatos de dados da IBM remontam à década de 1960 e frequentemente codificam sinalizadores como bits únicos em uma palavra para economizar armazenamento. À medida que os formatos foram modificados, os bytes do sinalizador foram adicionados no final dos registros existentes para manter a compatibilidade com versões anteriores. A documentação para um registro SMF, por exemplo, pode mostrar o código da linguagem assembly para testar três bits individuais em três palavras diferentes em um único registro para decidir que os dados eram um arquivo de entrada. Eu sei muito menos sobre as informações internas do TCP / IP, mas você também pode encontrar sinalizadores de bits.
fonte
O operador ^ é o bit a bit-xor (consulte &, |). O resultado para um par de bits é,
Então a expressão,
inverte / vira o 0º bit de x (deixando outros bits inalterados).
Considere se x pode ter valores além de 0x0 e 0x1? Quando x é um campo de bit único, ele pode ter apenas valores 0x0 e 0x1, mas quando x é um int (char / short / long / etc), os bits além do bit0 podem afetar o resultado da expressão.
A expressão fornecida permite que os bits ao lado do bit0 afetem o resultado,
Que tem uma veracidade equivalente como essa expressão (mais simples),
Observe que essa expressão examinaria apenas o bit0,
Portanto, a expressão apresentada realmente combina duas verificações de expressão,
O autor pretendia verificar apenas o bit0 e pretendia usar essa expressão,
Ou o autor pretendia obter os valores para bit1-bitN e xor do bit0?
fonte
Estou adicionando uma nova resposta porque ninguém realmente explicou como obter a resposta intuitivamente.
O inverso de
+
é-
.O inverso de
^
é^
.Como você resolve
0 != x - 1
parax
? Você+ 1
para os dois lados:0 + 1 != x - 1 + 1
→1 != x
.Como você resolve
0 != x ^ 1
parax
? Você^ 1
para os dois lados:0 ^ 1 != x ^ 1 ^ 1
→1 != x
.fonte
Eu acho que existem outros bits ou valores de campo de bits
x
, e isso pretende testar se apenas o bit de ordem inferior está definido. No contexto, eu acho que esse é o padrão e, portanto, a codificação deste e de algunsm
(provavelmente mais caros de codificar) podem ser ignorados, porque ambos devem ser o valor padrão, inicializados em um construtor ou similar.De alguma forma, o decodificador deve ser capaz de inferir que esses valores estão ausentes. Se eles estão no final de alguma estrutura, ela pode ser comunicada por um
length
valor sempre presente.fonte
O XOR é útil na enumeração de sinalizador C #. Para remover o sinalizador único do valor enum, é necessário usar o operador xor (consulte aqui )
Exemplo:
fonte
Existem muitas respostas boas, mas eu gosto de pensar de uma maneira mais simples.
Em primeiro lugar. Uma declaração if só é falsa se o argumento for zero. Isso significa que comparar diferente de zero é inútil.
Então isso nos deixa com:
Um XOR com um. O que um XOR faz é essencialmente detectar bits diferentes. Portanto, se todos os bits forem iguais, ele retornará 0. Como 0 é falso, o único momento em que retornará falso é se todos os bits forem iguais. Portanto, será falso se os argumentos forem os mesmos, verdadeiro se forem diferentes ... assim como o operador não é igual a .
De fato, a única diferença entre os dois é que
!=
retornará 0 ou 1, enquanto^
retornará qualquer número, mas a verdade do resultado será sempre a mesma. Uma maneira fácil de pensar sobre isso é.A "simplificação" final está convertendo
0x1
para decimal, que é 1. Portanto, sua declaração é equivalente a:fonte
^ é um operador XOR bit a bit
Se x = 1
aqui 0 == (x ^ 0x1)
Se x = 0
aqui 0! = (x ^ 0x1)
A tabela verdade de a xor b:
O código significa simplesmente
fonte
A técnica padrão que pode estar sendo usada, aqui, é repetir um idioma como aparece no contexto circundante para maior clareza, em vez de ofuscá-lo, substituindo-o por um idioma que é aritmeticamente mais simples, mas sem sentido no contexto.
O código circundante pode fazer referências frequentes
(x ^ 1)
ou o teste pode estar perguntando "se o bit 0 era o contrário, essa máscara de bits estaria vazia?".Dado que a condição faz com que algo seja
encode()
editado, pode ser que, no contexto, o estado padrão do bit 0 tenha sido invertido por outros fatores, e precisamos apenas codificar informações extras se algum dos bits se desviar do padrão (normalmente zero) )Se você tira a expressão do contexto e pergunta o que ela faz, ignora a intenção subjacente. Você também pode examinar a saída do assembly do compilador e ver que ele simplesmente faz uma comparação direta de igualdade com 1.
fonte
Como vejo as respostas até agora, falta uma regra simples para lidar com
XOR
s. Sem entrar em detalhes o que^
e0x
média (eif
, e!=
etc), a expressão0 != (x^1)
pode ser reformulado como segue usando o fato de que(a^a)==0
:fonte