# Opérations booléennes

Les opérations que l'on peut effectuer sur des bits sont théorisées par le mathématicien George Boole, dans le cadre de l'agèbre de Boole, ou calcul booléen.

En informatique, on peut avoir besoin de faire des opérations binaires dans deux cas :
- En programmation, quand ion veut valider si une condition est vraie ou fausse. En Python, cela se traduira par l'utilisation du type `bool` qui peut prendre les valeurs `True` ou `False`. C'est comme si on travaille avec un seul bit.
- Faire des calculs sur les bits d'un nombre pour le modifier. C'est une utilisation plus rare en python, mais que l'on retrouve dans le domaine de l'informatique embarquée (soit en Python, soit en C ou C++) ou du réseau. On travaille avec la représentation binaire sous-jacente aux nombres. Il faut alors réfléchir aux nombres comme à des suites de bits, et les opérations s'appliquent les bits 1 à 1.

Nous allons voir dans la suite les opérateurs classiques pour le calcul booléen. Ces opérateurs existent en python, nous verrons donc la syntaxe python également.

```admonish warning title="Attention"
Les opérateurs bit à bit en Python sont différents des opérateurs logiques utilisés dans les conditions. 

- Les opérateurs utilisés dans les conditions travaillent avec des types booléens `bool` (valeur `True` ou `False`) et renvoient un résultat booléen. Ils s'écrivent avec des lettres (`and or not`). Comme ils sont très courants, ça facilite la lecture du code.
- Les opérateurs bit à bit travaillent avec la représentation binaire des nombres entiers, c'est à dire directement avec les bits sous jacents aux nombres, et permettent de faire des calculs sur plusieurs bits à la fois. On travaille alors non pas avec des booléens, mais avec des nombres entiers vus comme des séries de bits. Ils sont représentés sous forme de symboles (`& | ~`)
```

## Table de vérité

Nous allons donner pour chaque opérateur une table de vérité. La table montre le résultat de toutes les opérations possibles avec cet opérateur.
Elle comporte plusieurs colonnes pour les **entrées** et la dernière colonne montre la valeur en **sortie**.

Nous utiliserons la valeur 1 pour dire Vrai ou `True` en python, et 0 pour dire Faux ou `False` en python.

## Opérateur ET

```admonish success title="A retenir"
L'opérateur ET ne renvoie 1 que si les deux arguments sont à 1. Sinon il renvoie 0.

**Si A ET B valent 1**

|A|B|A ET B|
|-|-|:-:|
|0|0|0|
|1|0|0|
|0|1|0|
|1|1|1|

En python :
- `and` lorsqu'on travaille avec des booléens 
- `&` lorsqu'on veut travailler en bit à bit
```

![ET](ET.svg)

## Opérateur OU

```admonish success title="A retenir"
L'opérateur OU renvoie 1 si au moins l'un des deux arguments est à 1. Sinon il renvoie 0.

**Si A vaut 1 ou si B vaut 1 ou si les deux valent 1**

|A|B|A OU B|
|-|-|:-:|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|1|

En python:
- `or` lorsqu'on travaille avec des booléens  
- `|` lorsqu'on veut travailler en bit à bit. 
```

![OU](OU.svg)

## Opérateur NON

```admonish success title="A retenir"
L'opérateur NON inverse la valeur du bit auquel il est appliqué.

|A|NON A|
|-|:-:|
|0|1|
|1|0|

En python: 
- `not` lorsqu'on travaille avec des booléens 
- `~` pour l'inversion bit à bit.
```

![NON](NOT.svg)

## Opérateur OU EXCLUSIF

```admonish success title="A retenir"
OU EXCLUSIF renvoie 1 si seulement l'un des deux arguments est à 1. Sinon il renvoie 0.

**Si A seulement vaut 1 ou si B seulement vaut 1**

|A|B|A XOR B|
|-|-|:-:|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|0|

En python, 
- il n'existe pas pour les `bool`
- `^` pour les opérations bit à bit
```

![XOR](XOR.svg)
