Что такое эквивалент С# (.NET 2.0) из _rotl
и _rotr
из С++?
С# побитовое вращение влево и поворот вправо
Ответ 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);