Je suis conscient de la prémisse de base de l'opération bitwise (bien qu'elles apprécieraient une explication "pour les nuls"); Cependant, je ne suis pas au courant du moment où il convient d'utiliser cette technique. P>
Ma compréhension est que Les architectures de processeurs plus anciennes pourraient effectuer des opérations binaire plus rapidement que d'autres opérations et il était donc avantageux de savoir comment pour les utiliser. Étant donné que cela n'est plus le cas; Est-il toujours approprié de les exécuter et, si oui, dans quel but et sous quelles conditions? (Je suis spécifiquement intéressé par le contexte C # mais je suis heureux de recevoir des réponses générales) p>
5 Réponses :
Le problème n'est pas tellement que les opérations bitwises sont plus rapides que les opérations entière (bien qu'elles soient habituellement), c'est qu'ils sont Conceptuellement octets et shorts et INTS sont vraiment minuscules forts> de bits et d'opérateurs bitwises sont des opérateurs de réseau booléen. Dans C # Nowadadays Opérateurs Bitwise sont principalement utilisés pour [indicateurs] code> énumérations et dans les calculs pour
gethascode code> mais il existe des façons sans fin que des matrices de bits peuvent être utilisées. P>
+1. Exemple pratique Si j'ai utilisé des opertions bitwises - Code de codage / décodage BASE64 / BASE32 (données est considérée comme une éventail de bits codé 6 ou 5 bits à la fois). Plus généralement, le code de compression / décompression utilise couramment les options binaire traitant des données comme sur la gamme de bits de Hige.
Vous êtes correct que, simplement parce que la langue vous donne une opération bitwise, vous ne devez pas les utiliser simplement parce que vous le pouvez. J'ai vu des gens utilisent des opérateurs bitwises lorsque vous travaillez avec de simples booléens et ce n'est pas ce qu'ils sont pour. P>
Les opérateurs Bitwise sont utiles lorsque vous travaillez avec des structures de données où des données ne sont pas alignées sur la limite d'octet. Généralement, cela se fait lorsque la bande passante (ou l'empreinte de la mémoire générale) est très importante. Je travaille sur le logiciel de streaming vidéo RTP et les opérations bitwises sont utilisées à la fois en lecture / construction de paquets de transmission RTP, ainsi que pour la lecture de flux de codec vidéo, qui sont souvent codés à l'aide de bits, pas d'octets. P>
Ils peuvent être vraiment utiles dans des situations de contrôle intégrées lorsque l'espace est à une prime. Par exemple, un seul octet de données peut représenter 8 bits d'E / S et des masques peuvent être utilisés pour extraire les bits d'intérêt d'un port d'E / S (par exemple, si loin du contrôle intégré, je le vois rarement que cela s'approcha d'être utilisé ces jours-ci. Dans le monde C #, il est beaucoup plus courant de voir des champs de booléens individuels pour chaque valeur d'intérêt, car les frais généraux ne sont vraiment pas une grosse affaire avec le matériel moderne (bien que vous puissiez courir dans une affaire ou deux où des opérations bitwises sont utilisées pour garder beaucoup de telles Drapeaux dans une seule variable). P>
Il y a aussi une application intéressante dans les graphiques. Un trucoche pour les curseurs ou les boîtes de liaison consiste à les ajouter en Xor'ing la forme du curseur avec l'image ci-dessous. L'exécution de la même opération entraînera à nouveau l'image d'origine. P> PIN0 = 1, PIN1 = 2, PIN2 = 4 , Pin3 = 8 code> et ainsi de suite, puis: p>
PIN0 code>, nous pouvons dire
port0 & pin0 == 0 code>. Li>
PIN1 code> sur 1, nous pouvons cay
port0 | = PIN1 code>. li>.
PIN2 code> sur 0, nous pouvons dire
port0 & = ~ pin2 code>. li>.
ul>
Une façon dont je me trouve à l'aide d'opérateurs bitwises de temps en temps consiste à générer des sous-ensembles d'une chaîne / une matrice donnée à l'aide d'un masque binaire, cela va comme suit: (Désolé, CODE C ++)
string s = "abcde"; for(int i = 0; i < 1<<s.size(); i++) { string tmp; for(int j = 0; j < s.size(); j++) if(i & 1<<j) tmp.push_back(s[j]); cout<<tmp<<endl; }
Les opérations Bitwise sont un excellent moyen de rechercher rapidement un drapeau pouvant être défini sur une variable.
L'exemple suivant met en évidence les avantages de l'utilisation des opérations bitwises sur un drapeau code> énumération de drapeau code> ainsi que de stocker un champ BitStuffed dans une base de données. Le champ BitStuffed peut alors facilement être vérifié pour voir s'il contient une valeur unique ou un sous-ensemble de valeurs à partir du drapeau Exemple: strong> p> A à part des opérations bitwises étant utilisées pour spécifier des valeurs dans l'énumération (effectuée au moment de la compilation ), vous pouvez utiliser l'énumération pour vérifier si le champ de permission de la base de données contient tout sous-ensemble des valeurs possibles. Du côté de la base de données, vous acquérirez la possibilité de créer des valeurs dans un seul champ - éliminant la nécessité d'avoir une colonne pour chaque autorisation et du côté du code, vous obtenez un moyen simple de rechercher une valeur. P> Exemple de bittstuffing (GRONDUCUSERSERS ET CARECADERS): STRAND> P> drapeau code> énumération. P>
Table de base de données avec un
Tinyint code> appelé
autorisation code>. Le champ est peuplé à l'aide d'une valeur créée avec l'énumération que les valeurs sont 2 ^ n. P>
public bool HasPermissions(Permission userPermissions, Permission permissionsToCheckFor)
{
return permissionsToCheckFor == Permission.None ?
false :
(userPermissions & permissionsToCheckFor) == permissionsToCheckFor;
}
C'est un exemple génial. Merci beaucoup. :-)
@ Maxim-gershkovich n'est pas un tirage au sort que vous ne verrez pas immédiatement ce que les utilisateurs seront si vous recherchez la valeur dans la base de données avec un client
Je suis d'accord avec @hcp. Les opérateurs bitwises provoquent un code inutilement illisible lorsqu'il existe de nombreuses autres moyens d'encoder ces informations. 1. L'optimisation de la vitesse / de la taille est la seule vraie raison de l'utiliser, et sauf si vous faites des systèmes embarqués, je dirais que très peu de raisons légitimes ont besoin de ce type d'accélération sur la plupart des systèmes d'aujourd'hui. Le compromis pour la lisibilité et la capacité de débogage en vaut la peine pour la vitesse dans la plupart des grands projets.
Selon MSDN : Les économies de taille peuvent être significatives si: 1. Vous vous attendez à ce que l'énumération soit utilisée comme champ dans une structure ou une classe très fréquemment instanciée. 2. Vous vous attendez à ce que les utilisateurs créent de grandes matrices ou des collections d'instances d'énumération. 3. Vous vous attendez à ce qu'un grand nombre d'instances de l'énumération soient sérialisées.
@ M1M1K, étant donné cet exemple, comment voudriez-vous encoder ces informations i>? Vous ne suggérez sûrement pas une colonne de bit pour chaque permission? Cet exemple ne servent pas la technique d'optimisation de la vitesse de la vitesse / de la taille B>. Il montre simplement une façon facile de gérer les autorisations. C'est ça. De plus, votre référence à MSDN cite des points non pertinents i> qui ne sont pas liés à drapeau code> Enums du tout! Enfin, les opérations bitwises sont autant un Core Programming Concept i> comme opérations de court-circuit . Les deux concepts de base faciles à suivre et à comprendre.
@ m1m1k je viens de me rendre compte que vous avez également évité ma réponse. Ma réponse a abordé la question immédiate qui est essentiellement «est-il toujours approprié d'utiliser des opérations sur les bits donnés compte des améliorations technologiques actuelles?» Et cette réponse montre comment il est toujours pertinent aujourd'hui.
Voulez-vous dire des changements de change et tels que ou toutes les opérations logiques aussi?
Pas de changement. Je comprends les opérations logiques.