web-dev-qa-db-fra.com

Avez-vous déjà dû utiliser le décalage de bits dans de vrais projets?

Avez-vous déjà dû utiliser décalage de bits dans de vrais projets de programmation? La plupart (sinon la totalité) des langues de haut niveau contiennent des opérateurs de décalage, mais quand auriez-vous réellement besoin de les utiliser?

78
Philip Morton

J'écris toujours du code pour les systèmes qui ne prennent pas en charge la virgule flottante dans le matériel. Dans ces systèmes, vous avez besoin du décalage de bits pour presque toute votre arithmétique.

Vous avez également besoin de changements pour générer des hachages. L'arithmétique polynomiale (CRC, Reed-Solomon Codes sont les applications dominantes) ou utilise également les décalages.

Cependant, les décalages ne sont utilisés que parce qu'ils sont pratiques et expriment exactement ce que l'auteur voulait. Vous pouvez émuler tous les décalages de bits avec multiplication si vous le souhaitez, mais ce serait plus difficile à écrire, moins lisible et parfois plus lent.

Les compilateurs détectent les cas où la multiplication peut être réduite à un décalage.

54
Nils Pipenbrinck

Oui, je les ai utilisées beaucoup de fois. Le twiddling de bits est important sur le matériel embarqué où les masques de bits sont très courants. C'est également important dans la programmation de jeux, lorsque vous avez besoin de toutes les dernières performances.

Edit: De plus, je les utilise beaucoup pour manipuler des bitmaps, par exemple changer la profondeur de couleur ou convertir RVB <-> BGR.

36
MrZebra
  • Créer de jolies valeurs de drapeau pour les énumérations (plutôt que de taper manuellement 1, 2, 4 ...)
  • Déballage des données des champs binaires (de nombreux protocoles réseau les utilisent)
  • Traversée de la courbe en Z
  • hacks de performance

Et je ne peux pas penser à de nombreux cas où ils sont utilisés. C'est généralement l'inverse - il y a un problème spécifique, et il s'avère que l'utilisation d'opérations sur les bits donnera les meilleurs résultats (généralement en termes de performances - temps et/ou espace).

24
Anonymous

Un endroit où je les utilise tout le temps est lors de la transposition de l'endian-ness des entiers pour les applications multiplateformes. Ils sont également parfois utiles (avec d'autres opérateurs de manipulation de bits) lors du blitting de graphiques 2D.

14
MattK

Je les ai utilisés plusieurs fois, mais presque toujours pour analyser un format de fichier binaire.

8
David Grant
6
Philip Reynolds

Oui, c'est toujours nécessaire.

Ici dans mon métier par exemple nous développons des logiciels de communication avec automate via le port série COMx. Il est nécessaire de gérer les bits dans un octet, nous utilisons les opérateurs de décalage gauche/droite et logique OR, XOR et AND au jour le jour.

Par exemple, supposons que nous devons activer le bit 3 (de droite à gauche) d'un octet:

C'est beaucoup plus efficace à faire:

Byte B;

B := B XOR 4;

Au lieu de:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

Cordialement.

6

Les décalages de bits sont rapides. Ils ont été implémentés dans des jeux d'instructions CPU bien avant les opérations de division et de module. Beaucoup d'entre nous ont utilisé des décalages de bits pour une arithmétique simple sur crayon et papier, mais non disponible sur nos processeurs.

Par exemple:

  • J'ai utilisé des décalages de bits pour des projets impliquant la prise en compte de grands composites dans leurs facteurs principaux.
  • J'ai également utilisé des décalages de bits pour trouver la racine carrée et cubique d'entiers arbitrairement grands.
6
eleven81

Quand j'ai écrit en langage assembleur, mon code était plein de décalage de bits et de masquage.

A-t-il également été assez important en C?.

Je ne l'ai pas beaucoup fait dans les langages JavaScript ou serveur.

La meilleure utilisation moderne est probablement de parcourir un tableau compact de valeurs booléennes représentées par des uns et des zéros. J'avais l'habitude de toujours quitter shift et de vérifier le bit de signe dans Assembly, mais dans les langues de niveau supérieur, vous comparez avec une valeur.

Par exemple, si vous avez 8 bits, vous vérifiez le bit supérieur avec "if (a> 127) {...}". Ensuite, vous avez quitté shift (ou multiplié par 2), faites un "et" avec 127 (ou faites une soustraction de 256 si le dernier bit a été défini), et recommencez.

4
Nosredna

Oui j'ai. Comme vous pouvez le penser, il est plus probable qu'il se trouve dans la programmation de bas niveau, par exemple le développement de pilotes de périphériques. Mais, j'ai travaillé sur un projet C # où j'ai dû développer un service web qui recevait des données d'appareils médicaux. Toutes les données binaires stockées par cet appareil ont été encodées en SOAP paquets, mais les données binaires ont été compressées et encodées. Donc, pour les décompresser, vous devrez faire beaucoup, beaucoup de manipulations de bits. Et en plus vous devriez faire beaucoup de décalage pour analyser toutes les informations utiles, par exemple le numéro de série du périphérique est une moitié inférieure du deuxième octet ou quelque chose comme ça. J'ai également vu des gens dans le monde .NET (C #) faire un l'utilisation du masquage de bits et de l'attribut de drapeau, personnellement, je n'ai jamais eu envie de le faire.

3
WebMatrix

Lors de la conversion de nombres du petit endian au grand format endian et vice versa

3
Ludwig Wensauer

Je travaille pour un fabricant de périphériques informatiques. J'ai rencontré et j'ai dû implémenter du code qui utilise des décalages de bits, presque tous les jours.

3
switchmode

oui. Je dois écrire des algorithmes de chiffrement avant et cela les utilise certainement.

Ils sont également utiles lors de l'utilisation d'entiers, etc. pour garder une trace des statuts.

3
kemiller2002

Je les ai beaucoup utilisés dans la compression/décompression d'images, où les bits d'une image bitmap étaient compressés. En utilisant http://en.wikipedia.org/wiki/Huffman_coding les éléments en cours de compression sont constitués de différents nombres de bits (ils ne sont pas tous alignés sur les octets), et donc vous devez changer de bit les lorsque vous les encodez ou les décodez.

3
ChrisW

Par exemple, dans l'implémentation de méthodes cryptographiques sur des langages tels que C, C++. Opérations sur les fichiers binaires, les algorithmes de compression et les listes logiques - l'opération au niveau du bit est toujours bonne =)

3
Anton

Le décalage de bits ne résout pas les problèmes de programmation de haut niveau, mais nous devons parfois résoudre des problèmes de niveau inférieur, et il est pratique de ne pas avoir à écrire une bibliothèque séparée en C pour le faire. C'est à ce moment qu'il est le plus utilisé, c'est ma supposition.

Je l'ai personnellement utilisé pour écrire un encodeur pour un convertisseur de jeu de caractères EBCDIC .

3
Michael Meadows

Trouvez la puissance la plus proche de deux supérieure ou égale au nombre donné:

1 << (int)(ceil(log2(given)))

Nécessaire pour la texturation sur du matériel qui ne prend pas en charge les tailles de texture arbitraires.

2
zoul

Transformée de Fourier rapide - FFT et sa technique de Cooley-Tukey nécessitera des opérations de décalage de bits.

2
LicenseQ

Le décalage de bits est beaucoup utilisé pour déchiffrer les protocoles des jeux en ligne. Les protocoles sont conçus pour utiliser le moins de bande passante possible, donc au lieu de transmettre le nombre de joueurs sur un serveur, les noms et ainsi de suite en int32, toutes les informations sont regroupées dans le moins d'octets possible. Ce n'est pas vraiment nécessaire de nos jours avec la plupart des gens qui utilisent le haut débit, mais quand ils ont été conçus à l'origine, les gens utilisaient des modems 56k pour les jeux, donc chaque bit comptait.

Les exemples les plus importants de cela se trouvent dans les jeux multijoueurs de Valve, en particulier Counter-Strike, Counter-Strike Source. Le protocole Quake3 est également le même, mais Unreal n'est pas aussi mince.

Voici un exemple (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

Bien sûr, que vous le considériez comme un vrai projet ou simplement un passe-temps (en C #), cela dépend de vous.

2
Chris S

Je l'utilise dans un projet de système embarqué qui doit lire les données EDID d'un moniteur. Certaines données dans un EDID sont encodées comme ceci:

Octet # 3:
Suppression horizontale - 8 bits inférieurs
Octet # 4:
Quartet inférieur: suppression horizontale - 4 bits supérieurs
Nibble supérieur: autre chose
1
Tobias Klüpfel

Oui, utilisé dans l'analyseur de flux de transport MPEG2-2. C'était plus facile et mieux lisible.

1
RvdK

Oui, lorsque vous effectuez une communication binaire entre Java et applications C #, l'une est le classement des octets big-endian et l'autre est little-endian (pas nécessairement dans cet ordre). J'ai créé une classe InputStream qui pourrait lire des nombres avec un ordre d'octets différent et utiliser le décalage d'octet pour fonctionner.

Parfois aussi, lorsque vous souhaitez mettre 4 courts métrages dans les 4 octets d'une longue, ce serait le cas de l'utilisation du décalage d'octets. Je pense que je l'ai fait il y a de nombreuses années ...

1
Ravi Wallau

J'ai dû écrire un programme pour analyser les fichiers .ifo sur les disques DVD. Ce sont les fichiers qui expliquent combien de titres, chapitres, menus, etc. sont sur le disque. Ils sont constitués de bits emballés de toutes tailles et alignements. Je soupçonne que de nombreux formats binaires nécessitent un décalage de bits similaire.

1
Steve Rowe

J'ai vu des opérateurs au niveau du bit utilisés lorsque plusieurs indicateurs étaient utilisés comme paramètre de propriété. Par exemple, le numéro 4 = 1 0 0 signifie que l'un des trois indicateurs est défini. Ce n'est pas bon pour l'API publique, mais cela peut accélérer les choses dans des cas spéciaux car la vérification des bits est rapide.

1
Lycha

Chaque bitblt-er que j'ai jamais écrit n'aurait pas pu être complété sans pouvoir faire glisser les bits vers la gauche et la droite.

1
Scott Evernden

Je les ai utilisés sur des jeux pour emballer un tas de drapeaux dans un seul octet/caractère pour les enregistrer sur une carte de données. Des choses comme le stockage du statut des déverrouillables, etc. Pas vraiment une exigence de nos jours, mais peuvent économiser du travail.

1
xan

Oui tout le temps. Comme ces macros pour compresser et décompresser une coordonnée 3 espaces vers/à partir d'un entier 32 bits:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        
0
chaos

Je les ai utilisés dans un évaluateur de main de poker.

Une main de poker est représentée comme un entier non signé 64 bits avec un 1 bit pour chaque carte présente dans la main. Grâce à une combinaison de décalage et de masquage, vous pouvez poser des questions telles que "donnez-moi tous les rangs pour lesquels j'ai au moins 3 cartes en main", etc.

C'est assez rapide, mais j'ai depuis appris des méthodes plus rapides où la main est représentée comme un tableau d'octets.

0
finnw

Sûr. Traiter avec masques d'affinité utilise le décalage de bits.

Par exemple, vous voudrez peut-être limiter une application à l'utilisation d'un nombre donné de processeurs (pour prendre de l'argent pour l'utilisation de chaque processeur) - utiliserez-vous des décalages de bits pour compter les bits dans le masque d'affinité?

0
sharptooth

Oui. Surtout dans un émulateur qui utilisait des octets de contrôle et d'état pour un pilote matériel. Chaque bit de l'octet de commande avait une signification spéciale et chaque bit de l'octet d'état avait une signification spéciale.

0
shortbaldman

Non, je n'ai jamais vraiment besoin de les utiliser. Je pense que ces opérations binaires sont un peu déconseillées pour les langages de haut niveau. Comme quelqu'un l'a dit, elles peuvent toujours être émulées avec d'autres expressions mathématiques, et comme elles ne sont presque jamais utilisées, elles pourraient être construites dans une bibliothèque externe. Le décalage de bits en Ruby ou python me semble vraiment bizarre, un peu comme mélanger un niveau haut et bas).

0
user35978

Le décalage de bits est également requis lors de la communication avec des équipements de "niveau inférieur", des boîtiers EQ ethernet-IO numériques ou des API, qui regroupent généralement les valeurs d'entrée/sortie individuelles en octets.

0
Harriv

Oui.

Le décalage de bits est extrêmement utile dans les applications intégrées, lorsque la mémoire est étroite et que la vitesse est primordiale.

Par exemple, au lieu d'effectuer une opération de multiplication coûteuse, vous pouvez effectuer le même calcul en utilisant uniquement l'addition et les décalages de bits, ce qui représente un énorme gain de temps:

c := 0
while b != 0
    if (b and 1) != 0
        c := c + a
    shift a left by one
    shift b right by one
return c
0
JRam930

Oui, le décalage de bits est utilisé à tout moment dans les logiciels embarqués de bas niveau. Il peut également être utilisé comme une astuce presque magique pour effectuer des opérations mathématiques extrêmement rapides, jetez un œil à

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

0
Joonas Pulakka

Je suis diplômé en informatique et j'utilise déjà des décalages de bits.

Ils sont bons pour stocker des drapeaux, pour travailler avec des hachages, etc., les gens l'ont déjà dit.

J'ai utilisé des opérations au niveau du bit une fois pour compacter 1 petite valeur entière (2 octets) et 2 caractères dans un entier. Cela m'a fait gagner beaucoup de mémoire par rapport aux projets de mes camarades.

Et ces opérations sont également très rapides parfois avec des calculs, par exemple lorsque vous devez étendre le type double ou utiliser une fonction pour manipuler des données à virgule flottante à l'aide de mantisses (voir les normes pour l'arithmectique à virgule flottante).

0
Giuliano

J'ai écrit (il y a de nombreuses années) une routine de sortie pour un projet qui a créé des feuilles de calcul Excel à l'aide de la structure Excel Oper. Il s'agissait d'un formant de fichier binaire qui nécessitait une grande quantité de torsion de bits. Le lien suivant donne un aperçu de la structure Oper Safari Books .

0
Aussie Craig

Je l'ai utilisé pour implémenter la conversion entre UTF-8 et UTF-32.

0
dan04

J'ai travaillé avec de nouvelles structures cryptographiques, en cachant les structures sérialisées (et les mises à jour ultérieures) derrière des additionneurs homomorphes. Beaucoup de hachages dépendent également des opérations sur les bits; se déplaçant parmi eux.

Cela impliquait beaucoup de changements de bits et de grosses opérations de grand nombre; tout en Java (certes, c'était une implémentation de référence/recherche).

Également fait des projets de compression (GZIP impl. En particulier), où vous devez emballer des bits assez fréquemment; ne peux pas imaginer tirer celui de sans << et >> (ou >>>, si vous êtes en Java).

Fondamentalement, si vous travaillez avec la cryptographie ou la compression, il y a de fortes chances que vous ayez besoin d'un décalage de bits à un moment ou à un autre.

0
Kevin Montrose

J'ai fait un peu de décalage en C #. L'application devait normaliser l'entrée audio de la parole, ce qui nécessitait plusieurs opérations mathématiques au niveau de l'échantillon audio.

0
Pablote

La plupart des paquets de données sont encore codés en bits. Si vous travaillez avec n'importe quel type de communications réseau de bas niveau, vous devrez jouer avec des bits.

Analyser également les paquets contenant du son et de la vidéo - je pense que même les balises MP3 utilisent quelques bits.

Plus important encore, ne pas être à l'aise avec les manipulations de bits signifie que vous manquerez probablement BEAUCOUP de meilleures façons de mettre en œuvre certaines opérations. Je veux dire, si vous avez affaire à l'existence de 5 milliards d'objets ordonnés, c'est la différence entre pouvoir les mettre tous dans le bélier assez confortablement pour une recherche instantanée ou les rechercher dans un fichier à chaque fois - sur une tâche comme celle-ci Je dirais que quelqu'un se qualifiant d'ingénieur logiciel qui l'a implémenté sans manipulation de bits était incompétent dans son travail.

0
Bill K

J'ai utilisé le décalage de bits dans un projet Web il y a quelque temps. C'était une application de commerce électronique où chaque produit avait un certain nombre d'attributs configurables. L'utilisateur pouvait choisir les attributs souhaités et l'interface utilisateur se mettait à jour pour fournir le prix et une référence pour les options sélectionnées.

Plutôt que de rechercher dans le magasin de données le SKU correspondant aux options de l'utilisateur, chaque combinaison d'options correspondait à un hachage spécifique, qui était en réalité un nombre créé à l'aide de mathématiques binaires. J'ai autorisé 4 bits (16 combinaisons) pour chaque option, jusqu'à cinq options, donc 20 bits au total. Pour calculer le hachage à partir des options de l'utilisateur, je boucle sur chaque attribut numéroté en ajoutant à la valeur de hachage:

for(var i = 0; i < getSku.arguments.length; i++)
{
    index = getAttributeIndex(i, getSku.arguments[i]);
    hash += (index+1) << (4*i);
}

C'était un peu plus rapide que de parcourir potentiellement des centaines de références comparant jusqu'à 5 valeurs à chaque fois.

0
Annika Backstrom

Je l'ai utilisé dans le calcul CRC.

0
Michał Piaskowski