36 votes

C# au niveau du bit tourner à gauche et tourner à droite

Qu'est-ce que le C# (équivalent de.NET 2.0) de _rotl et _rotr à partir de C++?

45voto

Joseph Points 18099

Est-ce que vous essayez de faire?

Jon Skeet répondu à cette question dans un autre site

Fondamentalement, ce que vous voulez, c'est

(pour la gauche)

(original << bits) | (original >> (32 -bits))

ou

(pour la droite)

(original >> bits) | (original << (32 -bits))

Aussi, comme Mehrdad a déjà suggéré, cela ne fonctionne que pour uint, qui est l'exemple que Jon donne ainsi.

24voto

Noldorin Points 67794

Il n'y a pas de langage intégré la fonctionnalité de rotation en C#, mais ces méthodes d'extension devrait faire l'affaire:

public static uint RotateLeft(this uint value, int count)
{
    return (value << count) | (value >> (32 - count))
}

public static uint RotateRight(this uint value, int count)
{
    return (value >> count) | (value << (32 - count))
}

Remarque: Comme Mehrdad points, le déplacement à droite (>>) pour les entiers signés est une particularité: il remplit l'Esm avec le bit de signe et non 0 comme il le fait pour les nombres non signés. J'ai maintenant changé les méthodes à prendre et renvoyer uint (entier 32 bits non signé), au lieu - c'est aussi dans une plus grande conformité avec le C++ rotl et rotr fonctions. Si vous souhaitez faire pivoter entiers, juste l'affaire avant de passer, et de nouveau jeté la valeur de retour, bien sûr.

Exemple d'utilisation:

int foo1 = 8.RotateRight(3); // foo1 = 1
int foo2 = int.MinValue.RotateLeft(3); // foo2 = 4

(À noter qu' int.MinValue est 111111111111111111111111 - 32 1 en binaire.)

9voto

Mehrdad Afshari Points 204872

La version naïve de déplacement ne fonctionne pas. La raison est, pour le déplacement des nombres signés va remplir la gauche bits bit de signe, pas 0:

Vous pouvez vérifier ce fait avec:

Console.WriteLine(-1 >> 1);

La manière correcte est:

public static int RotateLeft(this int value, int count)
{
    uint val = (uint)value;
    return (int)((val << count) | (val >> (32 - count)));
}

public static int RotateRight(this int value, int count)
{
    uint val = (uint)value;
    return (int)((value >> count) | (value << (32 - count)));
}

3voto

John Beyer Points 158

Notez que si vous souhaitez créer des surcharges qui opèrent sur les courts partie intégrante des valeurs, vous devez ajouter une étape supplémentaire, comme indiqué dans:

public static byte RotateLeft(
    this byte value,
    int count )
{
    // Unlike the RotateLeft( uint, int ) and RotateLeft( ulong, int ) 
    // overloads, we need to mask out the required bits of count 
    // manually, as the shift operaters will promote a byte to uint, 
    // and will not mask out the correct number of count bits.
    count &= 0x07;
    return (byte)((value << count) | (value >> (8 - count)));
}

Le masquage de l'opération n'est pas nécessaire pour les 32 bits et 64 bits des surcharges, comme les opérateurs de décalage de se prendre en charge pour ces tailles de gauche opérandes.

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