Quand utiliser les opérateurs Shift <> en C #?

J’étudiais les opérateurs de quart en C #, essayant de savoir quand les utiliser dans mon code.

J’ai trouvé une réponse mais pour Java, vous pourriez:

a) Accélérez les opérations de multiplication et de division d’entiers:

* 4839534 * 4 * peut être fait comme ceci: 4839534 << 2

ou

543894/2 peut être fait comme ceci: 543894 >> 1

Décalez les opérations beaucoup plus rapidement que la multiplication pour la plupart des processeurs.

b) Rassembler des stream d’octets en valeurs int

c) Pour accélérer les opérations avec des graphiques depuis les couleurs rouge, verte et bleue codées par octets distincts.

d) Emballer de petits nombres dans une seule longue …


Pour b, c et d, je ne peux pas imaginer ici un échantillon réel.

Est-ce que quelqu’un sait si nous pouvons accomplir tous ces éléments en C #? Existe-t-il une utilisation plus pratique pour les opérateurs de quart en C #?

Il n’est pas nécessaire de les utiliser à des fins d’optimisation, car le compilateur s’en charge pour vous.

Ne les utilisez que lorsque vous déplacez des bits, telle est la véritable intention de votre code (comme dans les autres exemples de votre question). Le rest du temps, utilisez simplement multiplier et diviser pour que les lecteurs de votre code puissent le comprendre d’un coup d’œil.

À moins d’une raison très convaincante, mon avis est que l’utilisation de tels trucs astucieux permet généralement de créer du code plus confus avec une valeur ajoutée minime. Les rédacteurs du compilateur sont un groupe intelligent de développeurs et connaissent beaucoup plus de ces astuces que le programmeur moyen. Par exemple, diviser un entier par une puissance de 2 est plus rapide avec l’opérateur de décalage qu’une division, mais ce n’est probablement pas nécessaire car le compilateur le fera pour vous. Vous pouvez le voir en regardant dans l’ensemble que le compilateur Microsoft C / C ++ et gcc effectuent ces optimisations.

Je vais partager un usage intéressant que j’ai rencontré par le passé. Cet exemple est copié sans vergogne d’une réponse supplémentaire à la question ” Que signifie l’atsortingbut Enum [drapeaux] en c #? ”

[Flags] public enum MyEnum { None = 0, First = 1 << 0, Second = 1 << 1, Third = 1 << 2, Fourth = 1 << 3 } 

Cela peut être plus facile à développer que d’écrire les valeurs littérales 1, 2, 4, 8, ... , en particulier lorsque vous dépassez 17 indicateurs.

Le compromis est que, si vous avez besoin de plus de 31 drapeaux ( 1 << 30 ), vous devez également veiller à spécifier votre énumération comme quelque chose avec une limite supérieure supérieure à un entier signé (en le déclarant comme public enum MyEnum : ulong , par exemple, ce qui vous donnera jusqu’à 64 drapeaux). Ceci est dû au fait...

 1 << 29 == 536870912 1 << 30 == 1073741824 1 << 31 == -2147483648 1 << 32 == 1 1 << 33 == 2 

En revanche, si vous définissez une valeur enum directement sur 2147483648, le compilateur renvoie une erreur.

Comme l'a souligné ClickRick, même si votre enum provient d'ulong, votre opération de décalage de bit doit être effectuée contre un ulong ou vos valeurs d'énum seront toujours cassées.

 [Flags] public enum MyEnum : ulong { None = 0, First = 1 << 0, Second = 1 << 1, Third = 1 << 2, Fourth = 1 << 3, // Compiler error: // Constant value '-2147483648' cannot be converted to a 'ulong' // (Note this wouldn't be thrown if MyEnum derived from long) ThirtySecond = 1 << 31, // so what you would have to do instead is... ThirtySecond = 1UL << 31, ThirtyThird = 1UL << 32, ThirtyFourth = 1UL << 33 } 

Consultez ces articles Wikipedia sur le système de nombres binarys et le changement arithmétique . Je pense qu’ils vont répondre à vos questions.

Les opérateurs de quart sont rarement rencontrés dans les applications métier aujourd’hui. Ils apparaîtront fréquemment dans du code de bas niveau qui interagit avec le matériel ou manipule des données compressées. Ils étaient plus communs à l’époque des 64k segments de mémoire.