Quels sont les cas d'utilisation réels des opérateurs binaires suivants?
- ET
- XOR
- NE PAS
- OU
- Décalage gauche / droite
language-agnostic
bitwise-operators
Louis Go
la source
la source
Réponses:
Champs de bits (drapeaux)
Ils sont le moyen le plus efficace de représenter quelque chose dont l'état est défini par plusieurs propriétés "oui ou non". Les listes de contrôle d'accès sont un bon exemple; si vous avez disons 4 autorisations discrètes (lecture, écriture, exécution, changement de politique), il est préférable de le stocker dans 1 octet plutôt que de le gaspiller 4. Ceux-ci peuvent être mappés à des types d'énumération dans de nombreuses langues pour plus de commodité.
La communication sur les ports / sockets
implique toujours des sommes de contrôle, la parité, des bits d'arrêt, des algorithmes de contrôle de flux, etc., qui dépendent généralement des valeurs logiques des octets individuels par opposition aux valeurs numériques, car le support peut uniquement être capable de transmettre un bit à un temps.
Compression, chiffrement
Les deux dépendent fortement des algorithmes au niveau du bit. Regardez l' algorithme de dégonflage pour un exemple - tout est en bits, pas en octets.
Machines à états finis
Je parle principalement du type de matériel embarqué, même si elles se trouvent également dans les logiciels. Ceux - ci sont combinatoires dans la nature - ils pourraient littéralement être obtenir « compilé » vers le bas à un tas de portes logiques, donc ils doivent être exprimés en
AND
,OR
,NOT
, etc.Graphiques Il n'y a guère assez d'espace ici pour entrer dans tous les domaines où ces opérateurs sont utilisés dans la programmation graphique.
XOR
(ou^
) est particulièrement intéressant ici car appliquer la même entrée une deuxième fois annulera la première. Les anciennes interfaces graphiques s'en servaient pour la mise en évidence de la sélection et d'autres superpositions, afin d'éliminer le besoin de redessiner coûteux. Ils sont toujours utiles dans les protocoles graphiques lents (c'est-à-dire le bureau à distance).Ce ne sont que les premiers exemples que j'ai trouvés - ce n'est pas une liste exhaustive.
la source
Est-ce étrange?
Est-il divisible par deux (pair)?
la source
Voici quelques idiomes courants traitant des drapeaux stockés sous forme de bits individuels.
Réglez le drapeau facturable:
Effacer l'indicateur CallerIDMissing:
Testez si CallerIDMissing et Chargeable sont définis:
la source
J'ai utilisé des opérations au niveau du bit dans la mise en œuvre d'un modèle de sécurité pour un CMS. Il y avait des pages auxquelles les utilisateurs pouvaient accéder s'ils faisaient partie des groupes appropriés. Un utilisateur peut être dans plusieurs groupes, nous avons donc dû vérifier s'il y avait une intersection entre les groupes d'utilisateurs et les groupes de pages. Nous avons donc attribué à chaque groupe un identifiant unique de puissance de 2, par exemple:
Nous OU ensemble ces valeurs, et stockons la valeur (comme un seul entier) avec la page. Par exemple, si une page est accessible aux groupes A et B, nous stockons la valeur 3 (qui en binaire est 00000011) comme contrôle d'accès aux pages. De la même manière, nous stockons une valeur d'identificateurs de groupe OR avec un utilisateur pour représenter les groupes dans lesquels ils se trouvent.
Donc, pour vérifier si un utilisateur donné peut accéder à une page donnée, il vous suffit de ET ensemble les valeurs et de vérifier si la valeur est non nulle. C'est très rapide car cette vérification est implémentée en une seule instruction, sans boucle, sans aller-retour dans la base de données.
la source
La programmation de bas niveau est un bon exemple. Vous pouvez, par exemple, avoir besoin d'écrire un bit spécifique dans un registre mappé en mémoire pour faire en sorte qu'un matériel fasse ce que vous voulez:
De plus,
htonl()
ethtons()
sont implémentés à l'aide des opérateurs&
et|
(sur les machines dont l' endianité (ordre des octets) ne correspond pas à l'ordre du réseau):la source
htons()
ethtonl()
sont des fonctions POSIX pour échanger unshort
ou unlong
de l'h
endianité de l'hôte ( ) à l'n
ordre des octets du réseau ( ).htonl()
pour uneint
valeur 32 bits ?long
signifie 64 bits dans de nombreuses langues.Je les utilise pour obtenir des valeurs RVB (A) à partir de valeurs de couleurs emballées, par exemple.
la source
(a & b) >> c
est plus de 5 fois plus rapide quea % d / e
(les deux façons d'extraire une seule valeur de couleur d'un int représentant ARGB). Respectivement, 6,7 s et 35,2 s pour 1 milliard d'itérations.%
n'est pas l'opérateur Module, c'est l'opérateur Restant. Ils sont équivalents pour les valeurs positives mais diffèrent par les valeurs négatives. Si vous fournissez les restrictions appropriées (en passant unuint
au lieu deint
par exemple), les deux exemples doivent avoir la même vitesse.Quand j'ai un tas de drapeaux booléens, j'aime les stocker tous dans un int.
Je les fais sortir en utilisant ET au niveau du bit. Par exemple:
etc.
la source
if (flags.feature_one_is_one) { // turn on feature }
. C'est dans la norme ANSI C, donc la portabilité ne devrait pas être un problème.& = ET:
Masque des bits spécifiques.
Vous définissez les bits spécifiques qui doivent être affichés ou non affichés. 0x0 & x effacera tous les bits d'un octet tandis que 0xFF ne changera pas x. 0x0F affichera les bits dans le quartet inférieur.
Conversion:
pour convertir des variables plus courtes en variables plus longues avec une identité binaire, il est nécessaire d'ajuster les bits car -1 dans un entier est 0xFFFFFFFF tandis que -1 dans un long est 0xFFFFFFFFFFFFFFFF. Pour préserver l'identité, vous appliquez un masque après la conversion.
| = OU
Définissez les bits. Les bits seront définis indépendamment s'ils sont déjà définis. De nombreuses infrastructures de données (champs binaires) ont des indicateurs comme IS_HSET = 0, IS_VSET = 1 qui peuvent être définis indépendamment. Pour définir les indicateurs, vous appliquez IS_HSET | IS_VSET (en C et en assemblage, c'est très pratique à lire)
^ = XOR
Recherche des bits identiques ou différents.
~ = PAS
Flip bits.
On peut montrer que toutes les opérations binaires locales possibles peuvent être mises en œuvre par ces opérations. Donc, si vous le souhaitez, vous pouvez implémenter une instruction ADD uniquement par des opérations binaires.
Quelques merveilleux hacks:
http://www.ugcs.caltech.edu/~wnoise/base2.html
http://www.jjj.de/bitwizardry/bitwizardrypage.html
la source
= ~
, non|=
, ce qui est OU.& = AND
- Pourquoi voudrais-je effacer tous les bits, pourquoi voudrais-je vouloir obtenir une version non modifiée de l'octet, et que dois-je faire avec le quartet inférieur?xor
lui-même. Je peux penser à plusieurs raisons pour lesquelles vous voudrez peut-être extraire le quartet inférieur. Surtout si ce quartet inférieur fait partie d'une structure de données et que vous souhaitez l'utiliser comme masque ouOR
avec une autre structure.Le chiffrement est toutes les opérations au niveau du bit.
la source
Vous pouvez les utiliser comme un moyen rapide et sale de hacher des données.
la source
Je viens d'utiliser bitwise-XOR (
^
) il y a environ trois minutes pour calculer une somme de contrôle pour la communication série avec un automate ...la source
Bitwise & est utilisé pour masquer / extraire une certaine partie d'un octet.
Variable de 1 octet
En particulier, l'opérateur de décalage (<< >>) est souvent utilisé pour les calculs.
la source
Ceci est un exemple pour lire les couleurs d'une image bitmap au format octet
J'espère que ces petits exemples vous aideront ...
la source
Dans le monde abstrait de la langue moderne d'aujourd'hui, pas trop. L'entrée-sortie de fichier est une tâche facile qui me vient à l'esprit, bien qu'elle consiste à exercer des opérations au niveau du bit sur quelque chose déjà implémenté et n'implémente pas quelque chose qui utilise des opérations au niveau du bit. Néanmoins, à titre d'exemple simple, ce code illustre la suppression de l'attribut en lecture seule sur un fichier (afin qu'il puisse être utilisé avec un nouveau FileStream spécifiant FileMode.Create) en c #:
En ce qui concerne les implémentations personnalisées, voici un exemple récent: j'ai créé un "centre de messages" pour envoyer des messages sécurisés d'une installation de notre application distribuée à une autre. Fondamentalement, il est analogue au courrier électronique, avec Inbox, Outbox, Sent, etc., mais il a également une livraison garantie avec des accusés de lecture, il existe donc des sous-dossiers supplémentaires au-delà de "boîte de réception" et "envoyé". Ce que cela signifiait était une obligation pour moi de définir de manière générique ce qui est "dans la boîte de réception" ou ce qui est "dans le dossier envoyé". Du dossier envoyé, j'ai besoin de savoir ce qui est lu et ce qui n'est pas lu. De ce qui n'est pas lu, j'ai besoin de savoir ce qui est reçu et ce qui ne l'est pas. J'utilise ces informations pour créer une clause where dynamique qui filtre une source de données locale et affiche les informations appropriées.
Voici comment l'énumération est constituée:
Voyez-vous ce que cela fait? En anding (&) avec la valeur d'énumération "Inbox", InboundMemos, je sais que InboundMemosForMyOrders est dans la boîte de réception.
Voici une version réduite de la méthode qui crée et renvoie le filtre qui définit une vue pour le dossier actuellement sélectionné:
Extrêmement simple, mais une implémentation soignée à un niveau d'abstraction qui ne nécessite généralement pas d'opérations au niveau du bit.
la source
L'encodage Base64 en est un exemple. Le codage Base64 est utilisé pour représenter les données binaires sous forme de caractères imprimables pour l'envoi via des systèmes de messagerie (et à d'autres fins). Le codage Base64 convertit une série d'octets 8 bits en index de recherche de caractères 6 bits. Les opérations sur les bits, le décalage et le «ou», le «pas» sont très utiles pour implémenter les opérations sur les bits nécessaires au codage et au décodage Base64.
Bien sûr, ce n'est qu'un des innombrables exemples.
la source
Je suis surpris que personne n'ait choisi la réponse évidente pour l'ère d'Internet. Calcul des adresses réseau valides pour un sous-réseau.
http://www.topwebhosts.org/tools/netmask.php
la source
Les opérations au niveau du bit sont généralement plus rapides que la multiplication / division. Donc, si vous devez multiplier une variable x par 9, vous ferez ce
x<<3 + x
qui serait quelques cycles plus rapide quex*9
. Si ce code se trouve dans un ISR, vous économiserez du temps de réponse.De même, si vous souhaitez utiliser un tableau comme file d'attente circulaire, il serait plus rapide (et plus élégant) de gérer les contrôles de bouclage avec des opérations au niveau du bit. (la taille de votre baie doit être une puissance de 2). Par exemple:, vous pouvez utiliser à la
tail = ((tail & MASK) + 1)
place detail = ((tail +1) < size) ? tail+1 : 0
, si vous souhaitez insérer / supprimer.De plus, si vous souhaitez qu'un indicateur d'erreur contienne plusieurs codes d'erreur, chaque bit peut contenir une valeur distincte. Vous pouvez ET avec chaque code d'erreur individuel comme vérification. Ceci est utilisé dans les codes d'erreur Unix.
Un bitmap à n bits peut également être une structure de données vraiment cool et compacte. Si vous souhaitez allouer un pool de ressources de taille n, nous pouvons utiliser un n-bits pour représenter l'état actuel.
la source
Personne ne semble avoir mentionné les mathématiques à virgule fixe.
(Ouais, je suis vieux, ok?)
la source
Un nombre est-il
x
une puissance de 2? (Utile par exemple dans les algorithmes où un compteur est incrémenté et où une action ne doit être effectuée que le nombre de fois logarithmique)Quel est le bit le plus élevé d'un entier
x
? (Ceci peut par exemple être utilisé pour trouver la puissance minimale de 2 supérieure àx
)Quel est le
1
bit le plus bas d'un entierx
? (Aide à trouver le nombre de fois divisible par 2.)la source
x & -x
.Les opérateurs au niveau du bit sont utiles pour boucler des tableaux dont la longueur est une puissance de 2. Comme beaucoup de personnes l'ont mentionné, les opérateurs au niveau du bit sont extrêmement utiles et sont utilisés dans les indicateurs , les graphiques , les réseaux , le cryptage . Non seulement cela, mais ils sont extrêmement rapides. Mon utilisation préférée personnelle est de boucler un tableau sans conditions . Supposons que vous ayez un tableau basé sur un indice zéro (par exemple, l'indice du premier élément est 0) et que vous ayez besoin de le boucler indéfiniment. Par indéfiniment, je veux dire passer du premier élément au dernier et revenir au premier. Une façon de mettre en œuvre ceci est:
C'est l'approche la plus simple, si vous souhaitez éviter l' instruction if , vous pouvez utiliser l' approche module comme ceci:
L'inconvénient de ces deux méthodes est que l'opérateur de module est coûteux, car il recherche un reste après la division entière. Et la première méthode exécute une instruction if à chaque itération. Avec l'opérateur au niveau du bit, cependant, si la longueur de votre tableau est une puissance de 2, vous pouvez facilement générer une séquence comme
0 .. length - 1
en utilisant l'&
opérateur (au niveau du bit et) comme teli & length
. Donc, sachant cela, le code d'en haut devientVoici comment cela fonctionne. Au format binaire , chaque nombre dont la puissance de 2 est soustraite de 1 est exprimé uniquement avec des nombres. Par exemple, 3 en binaire est
11
, 7 est111
, 15 est1111
et ainsi de suite, vous avez l'idée. Maintenant, que se passe-t-il si vous&
n'importe quel nombre contre un nombre composé uniquement de ceux en binaire? Disons que nous faisons ceci:Si
num
est plus petit ou égal à 7, le résultat seranum
parce que chaque bit&
avec 1 est lui-même. Sinum
est plus grand que 7, pendant l'&
opération, l'ordinateur considérera les zéros de tête de 7 qui, bien sûr, resteront comme des zéros après l'&
opération, seule la partie arrière restera. Comme en9 & 7
binaire ça ressemblerale résultat sera 0001 qui est 1 en décimal et adresse le deuxième élément du tableau.
la source
Je les utilise pour les options de sélection multiple, de cette façon je ne stocke qu'une seule valeur au lieu de 10 ou plus
la source
il peut également être pratique dans un modèle relationnel sql, disons que vous avez les tableaux suivants: BlogEntry, BlogCategory
traditionnellement, vous pouvez créer une relation nn entre eux à l'aide d'une table BlogEntryCategory ou lorsqu'il n'y a pas beaucoup d'enregistrements BlogCategory, vous pouvez utiliser une valeur dans BlogEntry pour créer un lien vers plusieurs enregistrements BlogCategory comme vous le feriez avec des énumérations marquées, dans la plupart des SGBDR, il existe également un opérateur très rapide pour sélectionner sur cette colonne "marquée" ...
la source
Lorsque vous souhaitez uniquement modifier certains bits des sorties d'un microcontrôleur, mais que le registre dans lequel écrire est un octet, vous faites quelque chose comme ceci (pseudocode):
Bien sûr, de nombreux microcontrôleurs vous permettent de changer chaque bit individuellement ...
la source
Si jamais vous voulez calculer votre nombre mod (%) une certaine puissance de 2, vous pouvez utiliser
yourNumber & 2^N-1
, qui dans ce cas est le même queyourNumber % 2^N
.C'est probablement seulement utile étant une alternative au fonctionnement du module avec un très gros dividende qui est 2 ^ N ... Mais même alors, son augmentation de vitesse par rapport au fonctionnement du module est négligeable dans mon test sur .NET 2.0. Je soupçonne que les compilateurs modernes effectuent déjà des optimisations comme celle-ci. Quelqu'un en sait-il plus?
la source
%
l'opération Remainder, ils traitent les négatifs différemment. Cependant, si vous passezuint
à%
, le compilateur C # produira réellement du code machine en utilisant AND au niveau du bit lorsque le deuxième argument est une puissance pré-connue de deux.Je les ai vus utilisés dans des systèmes de contrôle d'accès basés sur les rôles.
la source
Il y a une utilisation réelle dans ma question ici -
Répondre à la première notification WM_KEYDOWN uniquement?
Lors de la consommation d'un message WM_KEYDOWN dans les fenêtres, le bit 30 de l'api C spécifie l'état de clé précédent. La valeur est 1 si la clé est enfoncée avant l'envoi du message, ou elle est nulle si la clé est enfoncée
la source
Ils sont principalement utilisés pour les opérations au niveau du bit (surprise). Voici quelques exemples concrets trouvés dans la base de code PHP.
Encodage de caractère:
Structures de données:
Pilotes de base de données:
Implémentation du compilateur:
la source
Chaque fois que j'ai commencé la programmation en C, j'ai compris les tables de vérité et tout ça, mais tout n'a pas cliqué sur la façon de l'utiliser réellement jusqu'à ce que je lise cet article http://www.gamedev.net/reference/articles/article1563.asp (qui donne des exemples concrets)
la source
x == 1
ety == 2
, alorsx || y
s'évalue à 1 etx | y
s'évalue à 0. Je ne vois pas non plus pourquoix^true
est supérieur à!x
d'aucune façon. C'est plus typant, moins idiomatique, et si cex
n'est pas le cas,bool
ce n'est pas fiable.x^true
est supérieur à!x
estsome->complicated().member->lookup ^= true;
Il n'y a pas de versions à affectation composée d'opérateurs unaires.Je ne pense pas que cela compte comme bit à bit, mais le tableau de ruby définit les opérations de set via les opérateurs bit à bit entiers normaux. Alors
[1,2,4] & [1,2,3] # => [1,2]
. De même poura ^ b #=> set difference
eta | b #=> union
.la source
La solution linéaire Tower Of Hanoi utilise des opérations au niveau du bit pour résoudre le problème.
L'explication de cette solution se trouve ici
la source