Pergunta

Estou confuso sobre quando devo usar operadores booleanos versus operadores bit a bit

  • and contra &
  • or contra |

Alguém poderia me esclarecer quando devo usar cada um e quando usar um em vez do outro afetará meus resultados?

Foi útil?

Solução

Aqui estão algumas diretrizes:

  • Operadores booleanos são geralmente usados ​​em boleano valores, mas operadores bit a bit são geralmente usados ​​em inteiro valores.
  • Operadores booleanos são curto-circuito mas os operadores bit a bit são não curto-circuito.

O comportamento de curto-circuito é útil em expressões como esta:

if x is not None and x.foo == 42:
    # ...

Isso não funcionaria corretamente com o bit a bit & operador porque ambos os lados seriam sempre avaliados, dando AttributeError: 'NoneType' object has no attribute 'foo'.Quando você usa o booleano andoperador, a segunda expressão não é avaliada quando a primeira é False.De forma similar or não avalia o segundo argumento se o primeiro for True.

Outras dicas

Em teoria, and e or venha direto da lógica booleana (e, portanto, opera em dois booleanos para produzir um booleano), enquanto & e | Aplique o booleano e/ou os bits individuais de números inteiros. Há muitas perguntas aqui sobre como o último funciona exatamente.

Aqui estão as diferenças práticas que potencialmente afetam seus resultados:

  1. and e or curto-circuito, ou seja True or sys.exit(1) não sairá, porque por um determinado valor (True or ..., False and ...) do primeiro operando, o segundo não alteraria o resultado = não precisa ser avaliado. Mas | e & Não curto -circuito - True | sys.exit(1) joga você fora do repl.
  2. (Aplica -se apenas a alguns idiomas com sobrecarga do operador, incluindo Python :) & e | são operadores regulares e podem ser sobrecarregados - and e or são forjados no idioma (embora pelo menos em Python, o método especial para a coerção para boolean possa ter efeitos colaterais).
  3. (Aplica -se apenas a alguns idiomas [veja o comentário de Kennytm] :) and e or retornar (sempre? Nunca realmente entendeu isso, nem eu precisava) o valor de um operando em vez de True ou False. Isso não muda o significado das expressões booleanas em condições - 1 or True é 1, mas 1 é verdade também. Mas já foi usado para emular um operador condicional (cond ? true_val : false_val na sintaxe C, true_val if cond else false_val em Python desde alguns anos). Por & e |, o tipo de resultado depende de como os operando sobrecarregam os respectivos métodos especiais (True & False é False, 99 & 7 é 3, para conjuntos são sindicatos/interseção ...).

Mas mesmo quando por exemplo a_boolean & another_boolean funcionaria de forma idêntica, a solução certa está usando and - simplesmente porque and e or estão associados à expressão e condição booleanos enquanto & e | Fique de acordo com bits girando.

Aqui está uma diferença adicional, que me deixou intrigada por um tempo agora: porque & (e outros operadores bit newwise) têm uma precedência mais alta do que and (e outros operadores booleanos) As seguintes expressões avaliam para diferentes valores:

0 < 1 & 0 < 2

contra

0 < 1 and 0 < 2

Ou seja, os primeiros rendimentos False como é equivalente a 0 < (1 & 0) < 2, por isso 0 < 0 < 2, por isso 0 < 0 and 0 < 2.

Se você está tentando fazer operações booleanas em elementos em numpy, a resposta é um pouco diferente. Você pode usar & e | para operações booleanas em termos de elemento, mas and e or retornará o erro de valor.

Para estar do lado seguro, você pode usar o funções lógicas numpy.

np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False,  True], dtype=bool)

np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False,  True], dtype=bool)

A operação booleana são operações lógicas.

Operações bitwewe são operações em bits binários.

Operações bitwewe:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

As operações:

And & 1 if both bits are 1, 0 otherwise
Or  | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit

Alguns dos usos de operações bit -bowise:

1) Configuração e limpeza de bits

Operações booleanas:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 

A dica está no nome:

  • Os operadores booleanos são para executar operações lógicas (Teste de verdade comum na programação e lógica formal)
  • Os operadores bitwew são para "Limbo de bits" (Manipulação de baixo nível de bits nos tipos de dados byte e numéricos)

Embora seja possível e às vezes desejável (normalmente por razões de eficiência) executar operações lógicas com operadores bit -bitwise, geralmente os deve evitá -los para tais fins para evitar bugs sutis e efeitos colaterais indesejados.

Se você precisar manipular bits, os operadores bit -bit são construídos. O livro divertido: Hackers deleite Contém alguns exemplos legais e genuinamente úteis do que pode ser alcançado com a variação de bits.

A regra geral é usar o operador apropriado para os operandos existentes. Use operadores booleanos (lógicos) com operandos booleanos e operadores bitwise com operandos integrais (mais largos) (Nota: Falso é equivalente a 0, e Verdadeiro para 1). O único cenário "complicado" é aplicar operadores booleanos a operandos não booleanos.
Vamos dar um exemplo simples, conforme descrito em Então]: Python - diferenças entre 'e' e '&' [duplicado: 5 & 7 vs. 5 and 7.

Para o bit a bit e (&), as coisas são bem diretas:

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

Para o lógico e, aqui está o que Python 3]: Operações booleanas estados (ênfase é meu):

(Observe que nem e nem ou restringir o valor e o tipo que eles retornam Falso e Verdadeiro, mas sim devolver o último argumento avaliado.

Exemplo:

>>> 5 and 7
7
>>> 7 and 5
5

Claro, o mesmo se aplica a | vs. ou.

Boolean 'e' vs. bitwise '&':

Pseudo-código/python me ajudou a entender a diferença entre estes:

def boolAnd(A, B):
    # boolean 'and' returns either A or B
    if A == False:
        return A
    else:
        return B

def bitwiseAnd(A , B):
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.)

    binA = binary(A)
    binB = binary(B)



    # perform boolean 'and' on each pair of binaries in (A, B)
    # then return the result:
    # equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])

    # assuming binA and binB are the same length
    result = []
    for i in range(len(binA)):
      compar = boolAnd(binA[i], binB[i]) 
      result.append(compar)

    # we want to return a string of 1s and 0s, not a list

    return ''.join(result)

Operações Lógicas

geralmente são usados ​​para instruções condicionais.Por exemplo:

if a==2 and b >10 then /*Do something...*/ endif Isso significa que se ambas as condições((a==2) (b>10)) forem verdadeiras ao mesmo tempo, o corpo da instrução condicional pode ser executado.

Operações bit a bit

Operações bit a bit podem ser usadas para manipulação e extração de dados.Por exemplo, se você deseja extrair quatro LSB (Least Significant Bits) de um número inteiro, você pode fazer o seguinte:

Extração:

poo & 0x000F

Mascaramento:

poo | 0xFFF0

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top