Проблема с побитовым сдвигом ствола, поворотом влево и вправо в С#

В С++ у меня есть такой код.

    static UInt32 rol(UInt32 value, UInt32 bits)
    {
        bits &= 31;
        return ((value << bits) | (value >> (32 - bits)));
    }

    static UInt32 ror(UInt32 value, UInt32 bits)
    {
        bits &= 31;
        return ((value >> bits) | (value << (32 - bits)));
    }

как это будет выглядеть на С#? Я думаю точно так же.. только проблема

Ошибка 2 Оператор '>>' нельзя применить к операндам типа uint и uint
Ошибка 3 Оператор '>>' нельзя применить к операндам типа uint и uint
Ошибка 1 Оператор «‹‹» нельзя применять к операндам типа «uint» и «uint»
Ошибка 4. Оператор «‹‹» нельзя применять к операндам типа «uint» и «uint»


person SSpoke    schedule 02.09.2011    source источник
comment
Для справки: лучшие практики для выражения поворотов удобным для компилятора способом, избегая неопределенного поведения C: stackoverflow.com/questions/776508/. Когда bits == 0, этот код сдвинет 32b value на 32 бита. Надеюсь, это законно в С#.   -  person Peter Cordes    schedule 17.08.2015


Ответы (3)


Вы должны использовать тип int для правой переменной в операторах сдвига.

person oxilumin    schedule 02.09.2011
comment
разве это не испортит bits &= 31; логику? я должен создать другую переменную после этого? если я просто поменяю UInt32 bits на int bits, все исправится, но не сломается ли когда-нибудь эта логика bits AND 31? - person SSpoke; 03.09.2011
comment
Вы можете заменить bits &= 31 на bits %= 32. - person oxilumin; 03.09.2011
comment
Зачем использовать контракт? это превзойти исключения? Я не могу найти эту библиотеку в своей среде .NET. - person SSpoke; 03.09.2011
comment
Это просто способ записать if then throw выражение в одну строку, плюс у вас есть статическая проверка с библиотекой кодовых контрактов. Вы можете узнать об этом на сайте Microsoft. - person oxilumin; 03.09.2011
comment
@SSpoke: нет, на результат var &= 31; подписанность не влияет. Подпись изменяет значение только MSB. - person Ben Voigt; 03.09.2011

Вам нужно будет преобразовать правую часть оператора битового сдвига в int. Если вы произносите как (int)(32 - bits), это не должно влиять на вашу цель. Правая сторона просто ожидает int, вероятно, потому, что так проще, и маловероятно, что вы когда-либо захотите сдвинуть более 2 миллиардов битов.

person Michael Yoon    schedule 02.09.2011
comment
да ладно, я выбрал ваше решение .. проще исправить .. return ((value << (int)bits) | (value >> (int)(32 - bits))); и return ((value >> (int)bits) | (value << (int)(32 - bits))); - person SSpoke; 03.09.2011

Правильный операнд всегда должен быть типа int.

 int x << int bits
 uint x << int bits
 long x << int bits
 ulong x << int bits
person Senthil    schedule 02.09.2011