Почему F # побитовая панель оператора с 1 для подписанных типов? - PullRequest
3 голосов
/ 30 сентября 2010

Я смотрел на F # документ по битовым операциям:

Битовый оператор правого сдвига .В результате получается первый операнд с битами, сдвинутыми вправо на количество бит во втором операнде.Биты, сдвинутые из наименее значимой позиции, не превращаются в наиболее значимую позицию.Для беззнаковых типов старшие биты дополняются нулями.Для типов со знаком наиболее значимые биты дополняются единицами.Тип второго аргумента - int32.

Что послужило причиной такого выбора дизайна по сравнению с языком C ++ (и, вероятно, тоже C), где MSB дополняется нулями?Например:

int mask = -2147483648 >> 1; // C++ code

, где -2147483648 =

10000000 00000000 00000000 00000000

и маска равна 1073741824

, где 1073741824 =

01000000 00000000 00000000 00000000

Теперь, есливы пишете тот же код на F # (или C #), это действительно добавит MSB к ним, и вы получите -1073741824.

где -1073741824 =

11000000 00000000 00000000 00000000

Ответы [ 2 ]

6 голосов
/ 30 сентября 2010

Сдвиг со знаком имеет приятное свойство: смещение x вправо на n соответствует этажу (x / 2 n ).

В .NET существуют коды операций CIL для обоих типовоперации (shr, чтобы сделать смену со знаком и shr.un, чтобы сделать смену без знака).F # и C # выбирают, какой код операции использовать, основываясь на подписи типа, который смещается.Это означает, что если вы хотите другое поведение, вам просто нужно выполнить числовое преобразование до и после сдвига (что фактически не влияет на время выполнения из-за того, как числа хранятся в CLR - int32 в стеке неотличим от uint32),

5 голосов
/ 30 сентября 2010

Чтобы ответить на исправленный вопрос (в комментариях):

Стандарты C и C ++ не определяют результат смещения вправо отрицательного значения (оно либо определяется реализацией, либо не определено, я не могу вспомнить, какое).

Это потому, что стандарт был определен так, чтобы отражать наименьший общий знаменатель в терминах базового набора команд. Например, для выполнения истинного арифметического сдвига требуется несколько инструкций, если набор инструкций не содержит примитив asr. Это еще более усложняется тем фактом, что стандарт обязывает или свое или представление дополнения к двум.

...