Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Он включает предлагаемые изменения спецификаций, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующих собраниях по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/4682
Сводка
Оператор сдвига вправо без знака будет поддерживаться C# как встроенный оператор (для примитивных целочисленных типов) и в качестве определённого пользователем оператора.
Мотивация
При работе с целочисленным значением со знаком нередко нужно сдвигать биты вправо, не копируя бит высокого порядка на каждом сдвиге. Хотя этого можно достичь для примитивных целочисленных типов с обычным оператором сдвига, требуется преобразование в неподписанный тип до операции сдвига и преобразование обратно после неё. В контексте универсальных математических интерфейсов, которые библиотеки планируют открывать, это может создать дополнительные сложности, так как тип может не иметь заранее определенного или известного аналога без знака в универсальном математическом коде, хотя алгоритм может зависеть от возможности выполнения операции сдвига вправо без учета знака.
Подробный дизайн
Операторы и пунктуаторы
Раздел §6.4.6 будет изменен, чтобы включить оператор беззнакового сдвига вправо >>>.
unsigned_right_shift
: '>>>'
;
unsigned_right_shift_assignment
: '>>>='
;
Между маркерами в unsigned_right_shift и unsigned_right_shift_assignment продукциях не допускается никаких символов (даже пробелов). Эти построения обрабатываются особым образом, чтобы обеспечить правильную обработку списка параметров типа .
Операторы сдвига
Раздел §12.11 будет изменен, чтобы включить оператор >>> — оператор без знака вправо:
Операторы <<, >> и >>> используются для выполнения операций переключения битов.
shift_expression
: additive_expression
| shift_expression '<<' additive_expression
| shift_expression right_shift additive_expression
| shift_expression unsigned_right_shift additive_expression
;
Для операции формы x << count или x >> count или x >>> countразрешение перегрузки двоичных операторов (§12.4.5) применяется для выбора конкретной реализации оператора. Операнды преобразуются в типы параметров выбранного оператора, а тип результата — возвращаемый тип оператора.
Предопределенные операторы смены без знака будут поддерживать тот же набор подписей, которые предопределенные операторы со знаком смены поддерживаются сегодня в текущей реализации.
Сдвиг вправо:
int operator >>>(int x, int count); uint operator >>>(uint x, int count); long operator >>>(long x, int count); ulong operator >>>(ulong x, int count); nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);Оператор
>>>сдвигаетxвправо на несколько битов, вычисляемых, как описано ниже.Младшие биты
xотбрасываются, оставшиеся биты сдвигаются вправо, а позиции старших битов заполняются нулями.
Для предопределенных операторов число битов для смены вычисляется следующим образом:
- Если тип
xявляетсяintилиuint, число сдвигов определяется младшими пятью битамиcount. Другими словами, количество сдвигов вычисляется изcount & 0x1F. - Если тип
xявляетсяlongилиulong, число сдвигов задается шестью младшими битамиcount. Другими словами, количество сдвигов вычисляется изcount & 0x3F.
Если результирующее число сдвигов равно нулю, операторы сдвига просто возвращают значение x.
Операции смены никогда не вызывают переполнения и создают те же результаты в checked и unchecked контекстах.
Операторы назначения
Раздел §12.21 будет изменен, чтобы включить unsigned_right_shift_assignment следующим образом:
assignment_operator
: '='
| '+='
| '-='
| '*='
| '/='
| '%='
| '&='
| '|='
| '^='
| '<<='
| right_shift_assignment
| unsigned_right_shift_assignment
;
Целочисленные типы
Целочисленные типы в разделе §8.3.6 будут изменены, чтобы включить сведения об операторе >>>. Соответствующая точка маркера является следующей:
- Для двоичных
<<операторов>>и>>>левый операнд преобразуется в типT, гдеTявляется первым изint,uint,longиulong, которые могут полностью представлять все возможные значения операнда. Затем операция выполняется с точностью типаT, а тип результата —T.
Константные выражения
Оператор >>> будет добавлен в набор конструкций, разрешенных в константных выражениях §12.23.
Перегрузка оператора
Оператор >>> будет добавлен в набор перегруженных двоичных операторов в §12.4.3.
Поднятые операторы
Оператор >>> будет добавлен в набор двоичных операторов с поднятой формой в §12.4.8.
Приоритет оператора и ассоциативность
Раздел §12.4.2 будет изменен, чтобы добавить оператор >>> в категорию "Сдвиг" и оператор >>>= в категорию "Присваивание и лямбда-выражение".
Неоднозначность грамматики
Оператор >>> подвергается той же неоднозначности грамматики, описанной в §6.2.5 как обычный оператор >>.
Операторы
Раздел §15.10 будет отредактирован для включения оператора >>>.
overloadable_binary_operator
: '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '<<'
| right_shift | unsigned_right_shift | '==' | '!=' | '>' | '<' | '>=' | '<='
;
Двоичные операторы
Подпись оператора >>> применяется к тем же правилам, что и в §15.10.3 для подписи оператора >>.
Имя метаданных
Раздел "I.10.3.2 Двоичные операторы" в ECMA-335 уже зарезервирован для оператора сдвига без знака вправо - op_UnsignedRightShift.
Деревья выражений Linq
Оператор >>> не поддерживается в деревах выражений Linq, так как семантика предопределенных операторов >>> для подписанных типов не может быть точно представлена без добавления преобразований в неподписанный тип и обратно. Дополнительные сведения см. в https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.
Динамическая привязка
Похоже, что динамическая привязка использует элементы перечисления System.Linq.Expressions.ExpressionType для передачи информации о типе двоичного оператора привязке среды выполнения. Поскольку у нас нет элемента, специально представляющего оператор сдвига вправо без знака, динамическая привязка для оператора >>> не будет поддерживаться, и раздел статической и динамической привязки (§12.3) будет изменён, чтобы отразить этот факт.
Недостатки
Альтернативы
Деревья выражений Linq
Оператор >>> будет поддерживаться в деревьях выражений LINQ.
- Для определяемого пользователем оператора будет создан узел BinaryExpression, указывающий на метод оператора.
- Для предопределенных операторов
- Когда первый операнд является беззнаковым типом, будет создан узел BinaryExpression.
- Когда первый операнд является подписанным типом, преобразование первого операнда в неподписанный тип будет добавлено, будет создан узел BinaryExpression, и преобразование результата обратно в подписанный тип будет добавлено.
Например:
Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)
Resolution:
Отклонено, см. https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator для получения дополнительной информации.
Неразрешенные вопросы
Дизайнерские встречи
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications