web-dev-qa-db-fra.com

Opérateurs booléens vs opérateurs au niveau des bits

Je suis confus quant au moment d'utiliser un opérateur booléen ou binaire

and vs &, or vs |

Est-ce que quelqu'un pourrait m'éclairer sur le moment où je les utiliserais et quand utiliser l'un sur l'autre affectera mes résultats? 

56
Jiew Meng

Voici quelques lignes directrices:

  • Les opérateurs booléens sont généralement utilisés sur les valeurs boolean , tandis que les opérateurs au niveau des bits sont généralement utilisés sur les valeurs entier .
  • Les opérateurs booléens sont en court-circuit mais les opérateurs binaires sont non en court-circuit.

Le comportement de court-circuitage est utile dans des expressions comme celle-ci:

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

Cela ne fonctionnerait pas correctement avec l'opérateur binaire & car les deux côtés seraient toujours évalués, donnant AttributeError: 'NoneType' object has no attribute 'foo'. Lorsque vous utilisez l'opérateur booléen and, la deuxième expression n'est pas évaluée lorsque la première est fausse. De même, or n'évalue pas le deuxième argument si le premier est True.

53
Mark Byers

En théorie, and et or proviennent directement de la logique booléenne (et fonctionnent donc sur deux booléens pour produire un booléen), tandis que & et | appliquent les booléens et/ou les bits individuels d'entiers. Il y a beaucoup de questions ici sur la façon dont ce dernier fonctionne exactement.

Voici des différences pratiques qui peuvent affecter vos résultats:

  1. and et or court-circuiter, c'est-à-dire que True or sys.exit(1) ne se ferme pas, car pour une certaine valeur (True or ..., False and ...) du premier opérande, le second ne changerait pas le résultat = n'a pas besoin d'être évalué. Mais | et & ne court-circuite pas - True | sys.exit(1) vous jette hors du REPL.
  2. (Ne s'applique qu'à certains? Langages avec surcharge d'opérateurs, y compris Python. :) & et | sont des opérateurs normaux et peuvent être surchargés - and et or sont forgés dans le langage (bien qu'au moins en Python, la méthode spéciale de coercition sur boolean peut avoir Effets secondaires).
  3. (s'applique seulement à quelques langues [voir le commentaire de KennyTM] :) :) and et or retournent (toujours? jamais vraiment comprendre cela, je n'en avais pas besoin) la valeur d'un opérande au lieu de True ou False. Cela ne change pas la signification des expressions booléennes dans les conditions - 1 or True est 1, mais 1 est également vrai. Mais il était autrefois utilisé pour émuler un opérateur conditionnel (cond ? true_val : false_val en syntaxe C, true_val if cond else false_val en Python depuis quelques années). Pour & et |, le type de résultat dépend de la manière dont les opérandes surchargent les méthodes spéciales respectives (True & False est False, 99 & 7 est 3, pour les ensembles c'est son union/intersection ...).

Mais même quand, par exemple a_boolean & another_boolean fonctionnerait de manière identique, la bonne solution utilisant and - tout simplement parce que and et or sont associés à une expression booléenne et à une condition, alors que & et | correspondent à des virages.

18
user395760

Voici une autre différence, qui me laissait perplexe depuis quelque temps: parce que & (et d'autres opérateurs au niveau des bits) ont une priorité plus élevée que and (et d'autres opérateurs booléens), les expressions suivantes ont une valeur différente:

0 < 1 & 0 < 2

versus

0 < 1 and 0 < 2

À savoir, le premier produit False car il est équivalent à 0 < (1 & 0) < 2, d'où 0 < 0 < 2, d'où 0 < 0 and 0 < 2.

14
Arend

Si vous essayez d'effectuer des opérations booléennes par élément dans numpy, la réponse est quelque peu différente. Vous pouvez utiliser & et | pour les opérations booléennes par élément, mais and et or renverront une erreur de valeur.

Pour être sûr, vous pouvez utiliser les fonctions logiques 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)
4
C8H10N4O2

Les opérations booléennes sont des opérations logiques.

Les opérations au niveau du bit sont des opérations sur des bits binaires.

Opérations binaires:

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

Les opérations:

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

Quelques-unes des utilisations des opérations au niveau des bits:

1) Définition et effacement des bits

Opérations booléennes:

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

L'indice est dans le nom:

  • Les opérateurs booléens sont destinés à l'exécution de opérations logiques (test de vérité commun à la programmation et à la logique formelle)
  • Les opérateurs au niveau des bits sont destinés à "bit-twiddling" (manipulation de bas niveau des bits dans les types de données octet et numériques)

Bien qu'il soit possible et même parfois souhaitable (généralement pour des raisons d'efficacité) d'effectuer des opérations logiques avec des opérateurs au niveau du bit, vous devez généralement les éviter à cette fin pour éviter des bogues subtils et des effets secondaires indésirables.

Si vous devez manipuler des bits, les opérateurs au niveau du bit sont construits à cet effet. Le livre amusant: Hackers Delight contient quelques exemples intéressants et véritablement utiles de ce que l’on peut réaliser avec le bricolage.

2
Tendayi Mawushe

La règle générale consiste à utiliser l'opérateur approprié pour les opérandes existants. Utilisez des opérateurs booléens (logiques) avec des opérandes booléens et des opérateurs au niveau des bits avec des opérandes intégraux (plus larges) (remarque: False est équivalent à 0 et True à 1). Le seul scénario "délicat" consiste à appliquer des opérateurs booléens à des opérandes non booléens. 
Prenons un exemple simple, comme décrit dans [SO]: Python - Différences entre 'et' et '&' [duplicate] : 5 & 7vs.5 and 7.

Pour le bitwise and (&), les choses sont assez simples:

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

Pour le logique et, voici ce que [Python 3]: Opérations booléennes États (emphasis est le mien):

(Notez que ni et ni ni ne restreint la valeur et le type renvoyés à False et True, mais plutôt renvoie le dernier argument évalué .

Exemple:

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

Bien entendu, il en va de même pour | _ ​​vs.ou.

1
CristiFati

Booléen 'et' vs bitwise '&':

Pseudo-code/Python m'a aidé à comprendre la différence entre ceux-ci:

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)
0
geoffLangenderfer

Opérations logiques

sont généralement utilisés pour les instructions conditionnelles. Par exemple:

if a==2 and b >10 then /*Do something...*/ endif Cela signifie que si les deux conditions ((a = 2) (b> 10)) sont vraies en même temps, le corps de l'instruction conditionnelle peut être exécuté.

Opérations sur les bits

Les opérations sur les bits peuvent être utilisées pour la manipulation et l'extraction de données. Par exemple, si vous souhaitez extraire quatre bits de poids le moins significatif (LSB) d'un entier, procédez comme suit:

Extraction:

poo & 0x000F

Masquage:

poo | 0xFFF0

0
pooria