|
| 1 | +# Manipulation de bits |
| 2 | + |
| 3 | +_Read this in other languages:_ |
| 4 | +[english](README.md). |
| 5 | + |
| 6 | +#### Vérifier un bit (_get_) |
| 7 | + |
| 8 | +Cette méthode décale le bit correspondant (_bit shifting_) à la position zéro. |
| 9 | +Ensuite, nous exécutons l'opération `AND` avec un masque comme `0001`. |
| 10 | +Cela efface tous les bits du nombre original sauf le correspondant. |
| 11 | +Si le bit pertinent est `1`, le résultat est `1`, sinon le résultat est `0`. |
| 12 | + |
| 13 | +> Voir [getBit.js](getBit.js) pour plus de détails. |
| 14 | +
|
| 15 | +#### Mettre un bit à 1(_set_) |
| 16 | + |
| 17 | +Cette méthode met un bit à `1` en fonction d'un rang (`bitPosition`), |
| 18 | +créant ainsi une valeur qui ressemble à `00100`. |
| 19 | +Ensuite, nous effectuons l'opération `OU` qui met un bit spécifique |
| 20 | +en `1` sans affecter les autres bits du nombre. |
| 21 | + |
| 22 | +> Voir [setBit.js](setBit.js) pour plus de détails. |
| 23 | +
|
| 24 | +#### Mettre un bit à 0 (_clear_) |
| 25 | + |
| 26 | +Cette méthode met un bit à `1` en fonction d'un rang (`bitPosition`), |
| 27 | +créant ainsi une valeur qui ressemble à `00100`. |
| 28 | +Puis on inverse ce masque de bits pour obtenir un nombre ressemblant à `11011`. |
| 29 | +Enfin, l'opération `AND` est appliquée au nombre et au masque. |
| 30 | +Cette opération annule le bit. |
| 31 | + |
| 32 | +> Voir [clearBit.js](clearBit.js) pour plus de détails. |
| 33 | +
|
| 34 | +#### Mettre à jour un Bit (_update_) |
| 35 | + |
| 36 | +Cette méthode est une combinaison de l'"annulation de bit" |
| 37 | +et du "forçage de bit". |
| 38 | + |
| 39 | +> Voir [updateBit.js](updateBit.js) pour plus de détails. |
| 40 | +
|
| 41 | +#### Vérifier si un nombre est pair (_isEven_) |
| 42 | + |
| 43 | +Cette méthode détermine si un nombre donné est pair. |
| 44 | +Elle s'appuie sur le fait que les nombres impairs ont leur dernier |
| 45 | +bit droit à `1`. |
| 46 | + |
| 47 | +```text |
| 48 | +Nombre: 5 = 0b0101 |
| 49 | +isEven: false |
| 50 | +
|
| 51 | +Nombre: 4 = 0b0100 |
| 52 | +isEven: true |
| 53 | +``` |
| 54 | + |
| 55 | +> Voir [isEven.js](isEven.js) pour plus de détails. |
| 56 | +
|
| 57 | +#### Vérifier si un nombre est positif (_isPositive_) |
| 58 | + |
| 59 | +Cette méthode détermine un le nombre donné est positif. |
| 60 | +Elle s'appuie sur le fait que tous les nombres positifs |
| 61 | +ont leur bit le plus à gauche à `0`. |
| 62 | +Cependant, si le nombre fourni est zéro |
| 63 | +ou zéro négatif, il doit toujours renvoyer `false`. |
| 64 | + |
| 65 | +```text |
| 66 | +Nombre: 1 = 0b0001 |
| 67 | +isPositive: true |
| 68 | +
|
| 69 | +Nombre: -1 = -0b0001 |
| 70 | +isPositive: false |
| 71 | +``` |
| 72 | + |
| 73 | +> Voir [isPositive.js](isPositive.js) pour plus de détails. |
| 74 | +
|
| 75 | +#### Multiplier par deux |
| 76 | + |
| 77 | +Cette méthode décale un nombre donné d'un bit vers la gauche. |
| 78 | +Ainsi, toutes les composantes du nombre binaire (en puissances de deux) sont |
| 79 | +multipliées par deux et donc le nombre lui-même est |
| 80 | +multiplié par deux. |
| 81 | + |
| 82 | +``` |
| 83 | +Avant le décalage |
| 84 | +Nombre: 0b0101 = 5 |
| 85 | +Puissances de deux: 0 + 2^2 + 0 + 2^0 |
| 86 | +
|
| 87 | +Après le décalage |
| 88 | +Nombre: 0b1010 = 10 |
| 89 | +Puissances de deux: 2^3 + 0 + 2^1 + 0 |
| 90 | +``` |
| 91 | + |
| 92 | +> Voir [multiplyByTwo.js](multiplyByTwo.js) pour plus de détails. |
| 93 | +
|
| 94 | +#### Diviser par deux |
| 95 | + |
| 96 | +Cette méthode décale un nombre donné d'un bit vers la droite. |
| 97 | +Ainsi, toutes les composantes du nombre binaire (en puissances de deux) sont |
| 98 | +divisées par deux et donc le nombre lui-même est |
| 99 | +divisé par deux, sans reste. |
| 100 | + |
| 101 | +``` |
| 102 | +Avant le décalage |
| 103 | +Nombre: 0b0101 = 5 |
| 104 | +Puissances de deux: 0 + 2^2 + 0 + 2^0 |
| 105 | +
|
| 106 | +Après le décalage |
| 107 | +Nombre: 0b0010 = 2 |
| 108 | +Puissances de deux: 0 + 0 + 2^1 + 0 |
| 109 | +``` |
| 110 | + |
| 111 | +> Voir [divideByTwo.js](divideByTwo.js) pour plus de détails. |
| 112 | +
|
| 113 | +#### Inverser le signe (_Switch Sign_) |
| 114 | + |
| 115 | +Cette méthode rend positifs les nombres négatifs, et vice-versa. |
| 116 | +Pour ce faire, elle s'appuie sur l'approche "Complément à deux", |
| 117 | +qui inverse tous les bits du nombre et y ajoute 1. |
| 118 | + |
| 119 | +``` |
| 120 | +1101 -3 |
| 121 | +1110 -2 |
| 122 | +1111 -1 |
| 123 | +0000 0 |
| 124 | +0001 1 |
| 125 | +0010 2 |
| 126 | +0011 3 |
| 127 | +``` |
| 128 | + |
| 129 | +> Voir [switchSign.js](switchSign.js) pour plus de détails. |
| 130 | +
|
| 131 | +#### Multiplier deux nombres signés |
| 132 | + |
| 133 | +Cette méthode multiplie deux nombres entiers signés |
| 134 | +à l'aide d'opérateurs bit à bit. |
| 135 | +Cette méthode est basée sur les faits suivants: |
| 136 | + |
| 137 | +```text |
| 138 | +a * b peut être écrit sous les formes suivantes: |
| 139 | + 0 si a est zero ou b est zero ou les deux sont zero |
| 140 | + 2a * (b/2) si b est pair |
| 141 | + 2a * (b - 1)/2 + a si b est impair et positif |
| 142 | + 2a * (b + 1)/2 - a si b est impair et negatif |
| 143 | +``` |
| 144 | + |
| 145 | +L'avantage de cette approche est qu'à chaque étape de la récursion |
| 146 | +l'un des opérandes est réduit à la moitié de sa valeur d'origine. |
| 147 | +Par conséquent, la complexité d'exécution est `O(log(b))` |
| 148 | +où `b` est l'opérande qui se réduit de moitié à chaque récursion. |
| 149 | + |
| 150 | +> Voir [multiply.js](multiply.js) pour plus de détails. |
| 151 | +
|
| 152 | +#### Multiplier deux nombres positifs |
| 153 | + |
| 154 | +Cette méthode multiplie deux nombres entiers à l'aide d'opérateurs bit à bit. |
| 155 | +Cette méthode s'appuie sur le fait que "Chaque nombre peut être lu |
| 156 | +comme une somme de puissances de 2". |
| 157 | + |
| 158 | +L'idée principale de la multiplication bit à bit |
| 159 | +est que chaque nombre peut être divisé en somme des puissances de deux: |
| 160 | + |
| 161 | +Ainsi |
| 162 | + |
| 163 | +```text |
| 164 | +19 = 2^4 + 2^1 + 2^0 |
| 165 | +``` |
| 166 | + |
| 167 | +Donc multiplier `x` par `19` est equivalent à : |
| 168 | + |
| 169 | +```text |
| 170 | +x * 19 = x * 2^4 + x * 2^1 + x * 2^0 |
| 171 | +``` |
| 172 | + |
| 173 | +Nous devons maintenant nous rappeler que `x * 2 ^ 4` équivaut |
| 174 | +à déplacer`x` vers la gauche par `4` bits (`x << 4`). |
| 175 | + |
| 176 | +> Voir [multiplyUnsigned.js](multiplyUnsigned.js) pour plus de détails. |
| 177 | +
|
| 178 | +#### Compter les bits à 1 |
| 179 | + |
| 180 | +This method counts the number of set bits in a number using bitwise operators. |
| 181 | +The main idea is that we shift the number right by one bit at a time and check |
| 182 | +the result of `&` operation that is `1` if bit is set and `0` otherwise. |
| 183 | + |
| 184 | +Cette méthode décompte les bits à `1` d'un nombre |
| 185 | +à l'aide d'opérateurs bit à bit. |
| 186 | +L'idée principale est de décaler le nombre vers la droite, un bit à la fois, |
| 187 | +et de vérifier le résultat de l'opération `&` : |
| 188 | +`1` si le bit est défini et `0` dans le cas contraire. |
| 189 | + |
| 190 | +```text |
| 191 | +Nombre: 5 = 0b0101 |
| 192 | +Décompte des bits à 1 = 2 |
| 193 | +``` |
| 194 | + |
| 195 | +> Voir [countSetBits.js](countSetBits.js) pour plus de détails. |
| 196 | +
|
| 197 | +#### Compter les bits nécessaire pour remplacer un nombre |
| 198 | + |
| 199 | +This methods outputs the number of bits required to convert one number to another. |
| 200 | +This makes use of property that when numbers are `XOR`-ed the result will be number |
| 201 | +of different bits. |
| 202 | + |
| 203 | +Cette méthode retourne le nombre de bits requis |
| 204 | +pour convertir un nombre en un autre. |
| 205 | +Elle repose sur la propriété suivante: |
| 206 | +lorsque les nombres sont évalués via `XOR`, le résultat est le nombre |
| 207 | +de bits différents entre les deux. |
| 208 | + |
| 209 | +``` |
| 210 | +5 = 0b0101 |
| 211 | +1 = 0b0001 |
| 212 | +Nombre de bits pour le remplacement: 1 |
| 213 | +``` |
| 214 | + |
| 215 | +> Voir [bitsDiff.js](bitsDiff.js) pour plus de détails. |
| 216 | +
|
| 217 | +#### Calculer les bits significatifs d'un nombre |
| 218 | + |
| 219 | +Pour connaître les bits significatifs d'un nombre, |
| 220 | +on peut décaler `1` d'un bit à gauche plusieurs fois d'affilée |
| 221 | +jusqu'à ce que ce nombre soit plus grand que le nombre à comparer. |
| 222 | + |
| 223 | +``` |
| 224 | +5 = 0b0101 |
| 225 | +Décompte des bits significatifs: 3 |
| 226 | +On décale 1 quatre fois pour dépasser 5. |
| 227 | +``` |
| 228 | + |
| 229 | +> Voir [bitLength.js](bitLength.js) pour plus de détails. |
| 230 | +
|
| 231 | +#### Vérifier si un nombre est une puissance de 2 |
| 232 | + |
| 233 | +Cette méthode vérifie si un nombre donné est une puissance de deux. |
| 234 | +Elle s'appuie sur la propriété suivante. |
| 235 | +Disons que `powerNumber` est une puissance de deux (c'est-à-dire 2, 4, 8, 16 etc.). |
| 236 | +Si nous faisons l'opération `&` entre `powerNumber` et `powerNumber - 1`, |
| 237 | +elle retournera`0` (dans le cas où le nombre est une puissance de deux). |
| 238 | + |
| 239 | +``` |
| 240 | +Nombre: 4 = 0b0100 |
| 241 | +Nombre: 3 = (4 - 1) = 0b0011 |
| 242 | +4 & 3 = 0b0100 & 0b0011 = 0b0000 <-- Égal à zéro, car c'est une puissance de 2. |
| 243 | +
|
| 244 | +Nombre: 10 = 0b01010 |
| 245 | +Nombre: 9 = (10 - 1) = 0b01001 |
| 246 | +10 & 9 = 0b01010 & 0b01001 = 0b01000 <-- Différent de 0, donc n'est pas une puissance de 2. |
| 247 | +``` |
| 248 | + |
| 249 | +> Voir [isPowerOfTwo.js](isPowerOfTwo.js) pour plus de détails. |
| 250 | +
|
| 251 | +#### Additionneur complet |
| 252 | + |
| 253 | +Cette méthode ajoute deux nombres entiers à l'aide d'opérateurs bit à bit. |
| 254 | + |
| 255 | +Elle implémente un [additionneur](https://fr.wikipedia.org/wiki/Additionneur) |
| 256 | +simulant un circuit électronique logique, |
| 257 | +pour additionner deux entiers de 32 bits, |
| 258 | +sous la forme « complément à deux ». |
| 259 | +Elle utilise la logique booléenne pour couvrir tous les cas possibles |
| 260 | +d'ajout de deux bits donnés: |
| 261 | +avec et sans retenue de l'ajout de l'étape précédente la moins significative. |
| 262 | + |
| 263 | +Légende: |
| 264 | + |
| 265 | +- `A`: Nombre `A` |
| 266 | +- `B`: Nombre `B` |
| 267 | +- `ai`: ième bit du nombre `A` |
| 268 | +- `bi`: ième bit du nombre `B` |
| 269 | +- `carryIn`: un bit retenu de la précédente étape la moins significative |
| 270 | +- `carryOut`: un bit retenu pour la prochaine étape la plus significative |
| 271 | +- `bitSum`: La somme de `ai`, `bi`, et `carryIn` |
| 272 | +- `resultBin`: Le résultat complet de l'ajout de l'étape actuelle avec toutes les étapes moins significatives (en binaire) |
| 273 | +- `resultDec`: Le résultat complet de l'ajout de l'étape actuelle avec toutes les étapes moins significatives (en decimal) |
| 274 | + |
| 275 | +``` |
| 276 | +A = 3: 011 |
| 277 | +B = 6: 110 |
| 278 | +┌──────┬────┬────┬───────┬────────┬───────┬────────┬─────────┐ |
| 279 | +│ bit │ ai │ bi │ carryIn │ carryOut │ bitSum │ resultBin │ resultDec │ |
| 280 | +├──────┼────┼────┼───────┼────────┼───────┼────────┼─────────┤ |
| 281 | +│ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │ 1 │ |
| 282 | +│ 1 │ 1 │ 1 │ 0 │ 1 │ 0 │ 01 │ 1 │ |
| 283 | +│ 2 │ 0 │ 1 │ 1 │ 1 │ 0 │ 001 │ 1 │ |
| 284 | +│ 3 │ 0 │ 0 │ 1 │ 0 │ 1 │ 1001 │ 9 │ |
| 285 | +└──────┴────┴────┴───────┴────────┴───────┴────────┴─────────┘ |
| 286 | +``` |
| 287 | + |
| 288 | +> Voir [fullAdder.js](fullAdder.js) pour plus de détails. |
| 289 | +> Voir [Full Adder on YouTube](https://www.youtube.com/watch?v=wvJc9CZcvBc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8). |
| 290 | +
|
| 291 | +## Références |
| 292 | + |
| 293 | +- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) |
| 294 | +- [Negative Numbers in binary on YouTube](https://www.youtube.com/watch?v=4qH4unVtJkE&t=0s&index=30&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) |
| 295 | +- [Bit Hacks on stanford.edu](https://graphics.stanford.edu/~seander/bithacks.html) |
0 commit comments