43 votes

Que signifient deux parenthèses à angle gauche "<<" en C# ?

En gros, les questions du titre. Je regarde le code source de MVC 2 :

[Flags]
public enum HttpVerbs {
    Get = 1 << 0,
    Post = 1 << 1,
    Put = 1 << 2,
    Delete = 1 << 3,
    Head = 1 << 4
}

et je suis juste curieux de savoir ce que les doubles crochets d'angle gauche << fait.

0 votes

Si la question portait sur >> alors les réponses possibles devaient inclure la partie programmation générique de c#

130voto

pid Points 4092

Lorsque vous écrivez

1 << n

Vous changez la combinaison de bits 000000001 pour n fois à gauche et ainsi mis n en l'exposant de 2 :

2^n

Alors

1 << 10

C'est vraiment

1024

Pour une liste de 5 articles, par exemple, votre for fera un cycle de 32 fois.

0 votes

Donc c'est la même chose que for (int i = 0; i < Math.Pow(2, list.Count)); i++) ?

0 votes

@RobertFricke Je ferais attention en utilisant < avec int et double

8 votes

@Robert Fricke : Oui. Le décalage de bits est limité à une base de 2 (inconvénient) mais extrêmement plus rapide (avantage) que Math.Pow() qui est plus flexible et peut même avoir des bases et des exposants en virgule flottante. Il devient une seule instruction du code machine.

82voto

Selman22 Points 44788

Il s'appelle left-shift opérateur. Jetez un coup d'œil à la documentation

L'opérateur de décalage vers la gauche fait en sorte que la configuration binaire du premier opérande soit décalée vers la gauche du nombre de bits spécifié par le second opérande. Les bits libérés par l'opération de décalage sont remplis de zéros. Il s'agit d'un décalage logique et non d'une opération de décalage et de rotation.

Un exemple simple qui démontre le left-shift opérateur :

for (int i = 0; i < 10; i++)
{
    var shiftedValue = 1 << i;
    Console.WriteLine(" 1 << {0} = {1} \t Binary: {2}",i,shiftedValue,Convert.ToString(shiftedValue,2).PadLeft(10,'0'));
}

//Output:

// 1 << 0 = 1      Binary: 0000000001
// 1 << 1 = 2      Binary: 0000000010
// 1 << 2 = 4      Binary: 0000000100
// 1 << 3 = 8      Binary: 0000001000
// 1 << 4 = 16     Binary: 0000010000
// 1 << 5 = 32     Binary: 0000100000
// 1 << 6 = 64     Binary: 0001000000
// 1 << 7 = 128    Binary: 0010000000
// 1 << 8 = 256    Binary: 0100000000
// 1 << 9 = 512    Binary: 1000000000

Le déplacement d'un bit vers la gauche équivaut à une multiplication par deux. En fait, le déplacement de bits est plus rapide que la multiplication classique. Voyons un exemple qui démontre ce fait :

Disons que nous avons deux méthodes :

static void ShiftBits(long number,int count)
{
    long value = number;
    for (int i = 0; i < count; i+=128)
    {
          for (int j = 1; j < 65; j++)
          {
              value = value << j;
          }
          for (int j = 1; j < 65; j++)
          {
               value = value >> j;
          }
    }
}

static void MultipleAndDivide(long number, int count)
{
      long value = number;
      for (int i = 0; i < count; i += 128)
      {
            for (int j = 1; j < 65; j++)
            {
                value = value * (2 * j);
            }
            for (int j = 1; j < 65; j++)
            {
                value = value / (2 * j);
            }
      }
}

Et nous voulons les tester comme ceci :

ShiftBits(1, 10000000);
ShiftBits(1, 100000000);
ShiftBits(1, 1000000000);
...
MultipleAndDivide(1, 10000000);
MultipleAndDivide(1, 100000000);
MultipleAndDivide(1, 1000000000);
...

Voici les résultats :

Bit manipulation 10.000.000 times: 58 milliseconds
Bit manipulation 100.000.000 times: 375 milliseconds
Bit manipulation 1.000.000.000 times: 4073 milliseconds

Multiplication and Division 10.000.000 times: 81 milliseconds
Multiplication and Division 100.000.000 times: 824 milliseconds
Multiplication and Division 1.000.000.000 times: 8224 milliseconds

0 votes

Nous avons tendance à préférer les rotations par bit aux décalages par bit en cryptographie. Les décalages sont utilisés à certains endroits, mais ils sont loin d'être aussi courants que les rotations.

0 votes

C'est assez général. Je suis mal à l'aise avec ça pour vous dire la vérité. Je suis surtout mal à l'aise avec le fait que vous avez omis de mentionner qu'il effectue (valeur)*2^n très rapidement. De plus, les exemples que vous mentionnez sont (bien que vrais) à côté de la plaque, je pense.

3 votes

@jaked122 c'est assez maintenant ? :)

63voto

Aaronaught Points 73049

Ce serait le décalage binaire à gauche opérateur.

Pour chaque déplacement vers la gauche, la valeur est effectivement multipliée par 2. Ainsi, par exemple, en écrivant value << 3 multipliera la valeur par 8.

Ce qu'il fait réellement en interne, c'est déplacer tous les bits réels de la valeur d'une place vers la gauche. Ainsi, si vous avez la valeur 12 (décimale), en binaire, cela donne 00001100 ; en le déplaçant d'un endroit vers la gauche, cela se transformera en 00011000 ou 24.

57voto

Zaheer Ahmed Points 12945

Il est Décalage binaire à gauche Il fonctionne en décalant les chiffres de l'équivalent binaire du nombre par les nombres donnés (à droite).

donc :

temp = 14 << 2

L'équivalent binaire de 14 est 00001110 le décaler 2 fois signifie pousser le zéro du côté droit et décaler chaque chiffre du côté gauche, ce qui le rend 00111000 est égal à 56.

visual

Dans votre exemple :

i < (1 << list.Count)
  • 0000000001 = 1 si list.Count = 0 le résultat est 0000000001 = 1
  • 0000000001 = 1 si list.Count = 1 le résultat est 0000000010 = 2
  • 0000000001 = 1 si list.Count = 2 le résultat est 0000000100 = 4
  • 0000000001 = 1 si list.Count = 3 le résultat est 0000001000 = 8

et ainsi de suite. En général, il est égal 2 ^ list.Count (2 élevé à la puissance de list.Count)

36voto

Adam Robinson Points 88472

C'est le bithift gauche opérateur. Il décale le modèle binaire de l'opérande de gauche vers la gauche du nombre de chiffres binaires spécifiés dans l'opérande de droite.

Get = 1 << 0, // 1
Post = 1 << 1, // 2
Put = 1 << 2,  // 4
Delete = 1 << 3, // 8
Head = 1 << 4  // 16

Ceci est sémantiquement équivalent à lOperand * Math.Pow(2, rOperand)

0 votes

+1 pour avoir montré ce que fait le bithift de gauche dans ce cas.

8 votes

Ou plus précisément : 00001, 00010, 00100, 01000, 10000

1 votes

"par le nombre de chiffres binaires spécifiés dans l'opérande de droite" - en fait, ce n'est pas le cas. tout à fait droite ; pour 32 bits, par exemple, il ne prend en compte que les 5 premiers bits, donc << 33 est identique à << 1 . De même en mathématiques 64 bits, << 65 est identique à << 1 . Et le décalage à droite est encore plus complexe, car il faut tenir compte du signe pour savoir avec quoi recharger.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X