Que sont les opérateurs binaires?


130

Je suis quelqu'un qui écrit du code juste pour le plaisir et qui ne s'est pas vraiment plongé dans un contexte académique ou professionnel, donc des trucs comme ces opérateurs au niveau du bit m'échappent vraiment.

Je lisais un article sur JavaScript, qui prend apparemment en charge les opérations au niveau du bit. Je continue de voir cette opération mentionnée à certains endroits, et j'ai essayé de lire pour savoir de quoi il s'agit exactement, mais je ne semble tout simplement pas la comprendre. Alors que sont-ils? Des exemples clairs seraient formidables! :RÉ

Encore quelques questions - quelles sont les applications pratiques des opérations au niveau du bit? Quand pourriez-vous les utiliser?


2
Pour d'autres questions, vous pouvez ajouter une nouvelle question SO et faire référence à celle-ci. Vous obtiendrez probablement un meilleur ensemble de réponses de cette façon.
Greg Hewgill

Réponses:


187

Puisque personne n'a abordé le sujet de leur utilité:

J'utilise beaucoup les opérations au niveau du bit lorsque je travaille avec des indicateurs. Par exemple, si vous souhaitez passer une série d'indicateurs à une opération (par exemple File.Open(), avec le mode lecture et le mode écriture tous deux activés), vous pouvez les transmettre sous la forme d'une valeur unique. Ceci est accompli en attribuant à chaque drapeau possible son propre bit dans un ensemble de bits (octet, court, entier ou long). Par exemple:

 Read: 00000001
Write: 00000010

Donc si vous voulez passer en lecture ET en écriture, vous passerez (READ | WRITE) qui combine ensuite les deux

00000011

Qui peut alors être décrypté à l'autre extrémité comme:

if ((flag & Read) != 0) { //...

qui vérifie

00000011 &
00000001

qui retourne

00000001

qui n'est pas 0, donc l'indicateur spécifie READ.

Vous pouvez utiliser XOR pour basculer entre différents bits. Je l'ai utilisé lors de l'utilisation d'un drapeau pour spécifier des entrées directionnelles (haut, bas, gauche, droite). Par exemple, si un sprite se déplace horizontalement et que je veux qu'il se retourne:

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

Je XOR simplement la valeur actuelle avec (GAUCHE | DROITE) qui va désactiver la GAUCHE et la DROITE, dans ce cas.

Le décalage de bits est utile dans plusieurs cas.

x << y

est le même que

x * 2 y

si vous avez besoin de multiplier rapidement par une puissance de deux, mais faites attention au décalage d'un bit dans le bit supérieur - cela rend le nombre négatif à moins qu'il ne soit non signé. C'est également utile pour traiter différentes tailles de données. Par exemple, lire un entier de quatre octets:

int val = (A << 24) | (B << 16) | (C << 8) | D;

En supposant que A est l'octet le plus significatif et D le moins. Cela finirait par:

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

Les couleurs sont souvent stockées de cette façon (l'octet le plus significatif étant ignoré ou utilisé comme alpha):

A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000

Pour retrouver les valeurs, déplacez simplement les bits vers la droite jusqu'à ce qu'il soit en bas, puis masquez les bits d'ordre supérieur restants:

Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF

0xFFest le même que 11111111. Donc, essentiellement, pour Red, vous feriez ceci:

Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)

x << n, donc n doit être sous la forme de 2 ^ valeur?
Ahmed C le

28

Il convient de noter que les tables de vérité à un seul bit répertoriées comme autres réponses ne fonctionnent que sur un ou deux bits d'entrée à la fois. Que se passe-t-il lorsque vous utilisez des entiers, tels que:

int x = 5 & 6;

La réponse réside dans l'expansion binaire de chaque entrée:

  5 = 0 0 0 0 0 1 0 1
& 6 = 0 0 0 0 0 1 1 0
---------------------
      0 0 0 0 0 1 0 0

Chaque paire de bits dans chaque colonne est exécutée via la fonction "ET" pour donner le bit de sortie correspondant sur la ligne du bas. La réponse à l'expression ci-dessus est donc 4. La CPU a effectué (dans cet exemple) 8 opérations "ET" séparées en parallèle, une pour chaque colonne.

Je mentionne cela parce que je me souviens encore d'avoir ce "AHA!" moment où j'ai appris cela il y a de nombreuses années.


Wow, cela a beaucoup plus de sens maintenant. Cela semblait beaucoup plus compliqué qu'il ne l'est apparemment. Merci. Je ne sais pas laquelle choisir comme bonne réponse car il y en a beaucoup de bonnes, et je ne peux pas voter pour donc .. merci
cliquez sur

27

Les opérateurs au niveau du bit sont des opérateurs qui travaillent petit à petit.

AND est 1 uniquement si ses deux entrées sont 1.

OR vaut 1 si une ou plusieurs de ses entrées sont 1.

XOR est 1 seulement si exactement l'une de ses entrées est 1.

NOT est 1 uniquement si son entrée est 0.

Celles-ci peuvent être mieux décrites comme des tables de vérité. Les possibilités d'entrées sont en haut et à gauche, le bit résultant est l'une des quatre (deux dans le cas de NOT car il n'a qu'une seule entrée) valeurs affichées à l'intersection des deux entrées.

AND|0 1      OR|0 1
---+----    ---+----
  0|0 0       0|0 1
  1|0 1       1|1 1

XOR|0 1     NOT|0 1
---+----    ---+---
  0|0 1        |1 0
  1|1 0

Un exemple est que si vous ne voulez que les 4 bits inférieurs d'un entier, vous ET avec 15 (binaire 1111) ainsi:

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011

16

Voici les opérateurs au niveau du bit, tous pris en charge en JavaScript:

  • op1 & op2- L' ANDopérateur compare deux bits et génère un résultat de 1 si les deux bits sont 1; sinon, il renvoie 0.

  • op1 | op2- l' ORopérateur compare deux bits et génère un résultat de 1 si les bits sont complémentaires; sinon, il renvoie 0.

  • op1 ^ op2- L' EXCLUSIVE-ORopérateur compare deux bits et renvoie 1 si l'un des bits est 1 et il donne 0 si les deux bits sont 0 ou 1.

  • ~op1- L' COMPLEMENTopérateur permet d'inverser tous les bits de l'opérande.

  • op1 << op2- L' SHIFT LEFTopérateur déplace les bits vers la gauche, rejette le bit le plus à gauche et attribue au bit le plus à droite une valeur de 0. Chaque déplacement vers la gauche multiplie effectivement op1 par 2.

  • op1 >> op2- L' SHIFT RIGHTopérateur déplace les bits vers la droite, rejette le bit le plus à droite et attribue au bit le plus à gauche une valeur de 0. Chaque déplacement vers la droite divise effectivement op1 en deux. Le bit de signe le plus à gauche est conservé.

  • op1 >>> op2- L' opérateur SHIFT RIGHT- ZERO FILLdéplace les bits vers la droite, rejette le bit le plus à droite et attribue au bit le plus à gauche une valeur de 0. Chaque déplacement vers la droite divise effectivement op1 en deux. Le bit de signe le plus à gauche est ignoré.


"si les bits sont complémentaires" - waht?
Andrey Tyukin

@AndreyTyukin deux bits sont complémentaires si l'un d'eux est 1 et l'autre est 0.
Jeff Hillman

@JeffHillman Selon votre description dans le commentaire, 1 et 1 ne sont pas "complémentaires". Ensuite, je ne sais pas pourquoi 1 | 1donne 1et non 0, et comment |est alors censé être différent de ^. J'ai dû utiliser ce Q / A comme cible en double il y a quelques jours, et je souhaitais qu'après 10 ans, on ait un duplicata canonique plus clair pour ce genre de questions.
Andrey Tyukin

4

Pour le décomposer un peu plus, cela a beaucoup à voir avec la représentation binaire de la valeur en question.

Par exemple (en décimal):
x = 8
y = 1

sortirait (en binaire):
x = 1 000
y = 0001

À partir de là, vous pouvez effectuer des opérations de calcul telles que «et» ou «ou»; dans ce cas:
x | y =
1000 
0001 |
------
1001

ou ... 9 en décimal

J'espère que cela t'aides.


|est une opération OR?
Si8

Pour une raison quelconque, cela me semblait le plus logique. Toujours pas sûr de la x | y = 1000 0001 |partie
samayo

4

Lorsque le terme «bit à bit» est mentionné, il est parfois précisé qu'il ne s'agit pas d'un opérateur «logique».

Par exemple, en JavaScript, les opérateurs de bits traitent leurs opérandes comme une séquence de 32 bits (zéros et uns) ; Pendant ce temps, les opérateurs logiques sont généralement utilisés avec des valeurs booléennes (logiques) mais peuvent fonctionner avec des types non booléens.

Prenons l'exemple de expr1 && expr2.

Renvoie expr1 s'il peut être converti en faux; sinon, renvoie expr2. Ainsi, lorsqu'il est utilisé avec des valeurs booléennes, && renvoie true si les deux opérandes sont vrais; sinon, renvoie false.

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

Comme d'autres l'ont noté, 2 & 4 est un ET au niveau du bit, donc il retournera 0.

Vous pouvez copier ce qui suit dans test.html ou quelque chose et tester:

<html>
<body>
<script>
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
        + "2 && 4 = " + (2 && 4) + "\n"
        + "2 & 4 = " + (2 & 4));
</script>

3

Dans la programmation informatique numérique, une opération au niveau du bit fonctionne sur un ou plusieurs modèles de bits ou des chiffres binaires au niveau de leurs bits individuels. Il s'agit d'une action rapide et primitive directement prise en charge par le processeur et utilisée pour manipuler des valeurs à des fins de comparaisons et de calculs.

opérations :

  • ET au niveau du bit

  • OU au niveau du bit

  • pas au niveau du bit

  • XOR au niveau du bit

  • etc

Élément de liste

    AND|0 1        OR|0 1 
    ---+----      ---+---- 
      0|0 0         0|0 1 
      1|0 1         1|1 1 

   XOR|0 1        NOT|0 1 
   ---+----       ---+--- 
     0|0 1           |1 0 
     1|1 0

Par exemple.

    203: 1100 1011
AND  15: 0000 1111
------------------
  =  11: 0000 1011

Utilisations de l'opérateur bit à bit

  • Les opérateurs de décalage à gauche et à droite sont respectivement équivalents à la multiplication et à la division par x * 2 y .

Par exemple.

int main()
{
     int x = 19;
     printf ("x << 1 = %d\n" , x <<1);
     printf ("x >> 1 = %d\n", x >>1);
     return 0;
}
// Output: 38 9
  • L'opérateur & peut être utilisé pour vérifier rapidement si un nombre est pair ou impair

Par exemple.

int main()
{
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
 }
// Output: Odd
  • Recherche rapide minimum de x et y sans if elseinstruction

Par exemple.

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • Conversion décimale en binaire

Par exemple.

#include <stdio.h>
int main ()
{
    int n , c , k ;
    printf("Enter an integer in decimal number system\n " ) ;
    scanf( "%d" , & n );
    printf("%d in binary number
    system is: \n " , n ) ;
    for ( c = 31; c >= 0 ; c -- )
    {
         k = n >> c ;
         if ( k & 1 )
              printf("1" ) ;
         else
              printf("0" ) ;
      }
      printf(" \n " );
      return 0 ;
}
  • Le chiffrement de la porte XOR est une technique populaire, en raison de sa compatibilité et de sa réutilisation par le programmeur.
  • L'opérateur XOR bit à bit est l'opérateur le plus utile du point de vue des entretiens techniques.

le décalage au niveau du bit ne fonctionne qu'avec le nombre + ve

Il existe également un large éventail d'utilisation de la logique binaire


"complixblity et reare ..."?
Jonathan Cross

The left-shift and right-shift operators are equivalent to multiplication and division by x * 2y respectively.C'est vrai! muyiy.cn/question/program/102.html
xgqfrms

ma solution repl.it/@xgqfrms
xgqfrms

1

Cela pourrait aider à penser de cette façon. Voici comment fonctionne AND (&):

Il dit essentiellement que sont ces deux nombres, donc si vous avez deux nombres 5 et 3, ils seront convertis en binaire et l'ordinateur pensera

         5: 00000101
         3: 00000011

sont tous les deux un: 00000001 0 est faux, 1 est vrai

Ainsi, le ET de 5 et 3 est un. L'opérateur OR (|) fait la même chose sauf qu'un seul des nombres doit être un pour afficher 1, pas les deux.


-5

J'entendais sans cesse parler de la lenteur des opérateurs JavaScript binaires. J'ai fait quelques tests pour mon dernier article de blog et j'ai découvert qu'ils étaient 40% à 80% plus rapides que l'alternative arithmétique dans plusieurs tests. Peut-être étaient-ils lents. Dans les navigateurs modernes, je les adore.

J'ai un cas dans mon code qui sera plus rapide et plus facile à lire à cause de cela. Je vais garder les yeux ouverts pour en savoir plus.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.