Подтвердить что ты не робот

С# побитовое вращение влево и поворот вправо

Что такое эквивалент С# (.NET 2.0) из _rotl и _rotr из С++?

4b9b3361

Ответ 1

Это то, что вы пытаетесь сделать?

Jon Skeet ответил на это на другом сайте

В принципе, вы хотите

(слева)

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

или

(справа)

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

Кроме того, как уже предполагал Мехрдад, это работает только для uint, что является примером, который дает и Джон.

Ответ 2

Нет встроенной функции языка для вращения бит в С#, но эти методы расширения должны выполнять задание:

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))
}

Примечание.. Как указывает Мехрдад, правая смена (>>) для целых чисел со знаком является особенностью: она заполняет MSB знаковым битом, а не 0, как и для беззнаковых чисел. Теперь я изменил методы, чтобы взять и вернуть uint (беззнаковое 32-битное целое число) - это также в большей степени соответствует функциям С++ rotl и rotr. Если вы хотите повернуть целые числа, просто делайте их перед прохождением и, конечно, снова введите возвращаемое значение.

Пример использования:

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

(Обратите внимание, что int.MinValue равно 11111111111111111111111111 - 32 1s в двоичном формате.)

Ответ 3

Наивная версия смены не будет работать. Причина в том, что правые сдвиговые знаковые числа заполнят левые биты значком , а не 0:

Вы можете проверить этот факт с помощью:

Console.WriteLine(-1 >> 1);

Правильный способ:

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)));
}

Ответ 4

Обратите внимание, что если вы хотите создать перегрузки, которые работают с более короткими интегральными значениями, вам нужно добавить дополнительный шаг, как показано на рисунке:

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)));
}

Операция маскирования не требуется для 32-разрядных и 64-разрядных перегрузок, так как сами операторы сдвига позаботятся об этих размерах левых операндов.

Ответ 5

// if you are using string

string str=Convert.ToString(number,2);

str=str.PadLeft(32,'0');




//Rotate right


str = str.PadLeft(33, str[str.Length - 1]);

str= str.Remove(str.Length - 1);

number=Convert.ToInt32(str,2);



//Rotate left


str = str.PadRight(33, str[0]);

str= str.Remove(0,1);

number=Convert.ToInt32(str,2);