Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są przechwytywane w odpowiednich spotkania projektowego języka (LDM).
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem mistrza: https://github.com/dotnet/csharplang/issues/4682
Streszczenie
Operator bezznakowego przesunięcia w prawo będzie obsługiwany przez C# jako operator zdefiniowany przez użytkownika i jako wbudowany operator dla typów całkowitych.
Motywacja
Podczas pracy z podpisaną wartością całkowitą nie jest rzadkością, że trzeba przesuwać bity w prawo bez replikowania bitu o wysokiej kolejności na każdym przesunięciu. Chociaż można to osiągnąć dla określonych typów pierwotnych całkowitych za pomocą standardowego operatora przesunięcia, konieczne jest rzutowanie na typ niepodpisany przed operacją przesunięcia, a następnie rzutowanie z powrotem po jej wykonaniu. W kontekście ogólnych interfejsów matematycznych, które biblioteki planują udostępnić, może to być bardziej problematyczne, ponieważ typ może nie mieć zdefiniowanego lub wcześniej znanego niepodpisanego odpowiednika w ogólnym kodzie matematycznym, a algorytm może polegać na możliwości wykonania niepodpisanej operacji przesunięcia w prawo.
Szczegółowy projekt
Operatory i znaki interpunkcyjne
Sekcja §6.4.6 zostanie dostosowana w celu uwzględnienia operatora >>> - operatora niepodpisanego przesunięcia prawego:
unsigned_right_shift
: '>>>'
;
unsigned_right_shift_assignment
: '>>>='
;
Żadne znaki dowolnego rodzaju (nawet białe znaki) nie są dozwolone między tokenami w konstrukcjach unsigned_right_shift i unsigned_right_shift_assignment. Te produkcje są traktowane w szczególny sposób, aby umożliwić poprawną obsługę list typu_parametrów .
Operatory przesunięcia
Sekcja §12.11 zostanie dostosowana w celu uwzględnienia operatora >>> - operatora niepodpisanego przesunięcia prawego:
Operatory <<, >> i >>> służą do wykonywania operacji przesunięcia bitów.
shift_expression
: additive_expression
| shift_expression '<<' additive_expression
| shift_expression right_shift additive_expression
| shift_expression unsigned_right_shift additive_expression
;
W przypadku operacji formularza x << count lub x >> count lub x >>> countfunkcja rozpoznawania przeciążenia operatora binarnego (§12.4.5) jest stosowana w celu wybrania określonej implementacji operatora. Operandy są konwertowane na typy parametrów wybranego operatora, a typ wyniku jest zwracanym typem operatora.
Wstępnie zdefiniowane niepodpisane operatory przesunięcia będą obsługiwać ten sam zestaw podpisów, które obecnie obsługują wstępnie zdefiniowane operatory przesunięcia w bieżącej implementacji.
Shift w prawo:
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);Operator
>>>zmieniaxw prawo przez kilka bitów obliczonych zgodnie z poniższym opisem.Bity o niskiej kolejności
xsą odrzucane, pozostałe bity są przesunięte w prawo, a puste pozycje bitów o wysokiej kolejności są ustawione na zero.
W przypadku wstępnie zdefiniowanych operatorów liczba bitów do przesunięcia jest obliczana w następujący sposób:
- Gdy typ
xjestintlubuint, liczba przesunięć jest określana przez pięć najmłodszych bitówcount. Innymi słowy, liczba zmian jest obliczana zcount & 0x1F. - Gdy typ
xtolonglubulong, liczba przesunięć jest podawana przez sześć najmniej znaczących bitówcount. Innymi słowy, liczba zmian jest obliczana zcount & 0x3F.
Jeśli wynikowa liczba zmian wynosi zero, operatory przesunięcia po prostu zwracają wartość x.
Operacje przesunięcia nigdy nie powodują przepełnienia i generują te same wyniki w kontekstach checked i unchecked.
Operatory przypisania
Sekcja §12.21 zostanie skorygowana w celu uwzględnienia unsigned_right_shift_assignment w następujący sposób:
assignment_operator
: '='
| '+='
| '-='
| '*='
| '/='
| '%='
| '&='
| '|='
| '^='
| '<<='
| right_shift_assignment
| unsigned_right_shift_assignment
;
Typy całkowite
Sekcja dotyczącą typów całkowitych §8.3.6 zostanie dostosowana, aby uwzględnić informacje o operatorze >>>. Istotny punkt jest następujący:
- W przypadku operatorów
<<binarnych ,>>i>>>lewy operand jest konwertowany na typT, gdzieTjest pierwszym zint,uint,longiulong, które mogą w pełni reprezentować wszystkie możliwe wartości operandu. Następnie operacja jest wykonywana przy użyciu precyzji typuT, a typ wyniku jestT.
Wyrażenia stałe
Operator >>> zostanie dodany do zestawu konstrukcji dozwolonych w wyrażeniach stałych w §12.23.
Przeciążenie operatora
Operator >>> zostanie dodany do zestawu przeciążalnych operatorów binarnych w §12.4.3.
Operatory zniesione
Operator >>> zostanie dodany do zestawu operatorów binarnych pozwalających na podniesioną formę w §12.4.8.
Pierwszeństwo operatora i asocjacyjność
Sekcja §12.4.2 zostanie dostosowana w celu dodania operatora >>> do kategorii "Shift" i operatora >>>= do kategorii "Przypisanie i wyrażenie lambda".
Niejednoznaczności gramatyczne
Operator >>> podlega tym samym niejednoznacznościom gramatycznym opisanym w §6.2.5 jako zwykły operator >>.
Operatorów
Sekcja §15.10 zostanie dostosowana w celu uwzględnienia operatora >>>.
overloadable_binary_operator
: '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '<<'
| right_shift | unsigned_right_shift | '==' | '!=' | '>' | '<' | '>=' | '<='
;
Operatory binarne
Podpis operatora >>> podlega tym samym zasadom, co zasady w §15.10.3 dla podpisu operatora >>.
Nazwa metadanych
Sekcja "I.10.3.2 Operatory binarne" ECMA-335 już zarezerwowała nazwę operatora niepodpisanego przesunięcia prawego — op_UnsignedRightShift.
Drzewa wyrażeń Linq
Operator >>> nie będzie obsługiwany w drzewach wyrażeń Linq, ponieważ semantyka wstępnie zdefiniowanych operatorów >>> w typach podpisanych nie może być dokładnie reprezentowana bez dodawania konwersji do niepodpisanego typu i z powrotem. Aby uzyskać więcej informacji, zobacz https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.
Powiązanie dynamiczne
Wygląda na to, że powiązanie dynamiczne używa wartości z wyliczenia System.Linq.Expressions.ExpressionType, aby przekazać typ operatora binarnego do łącznika środowiska uruchomieniowego. Ponieważ nie mamy elementu członkowskiego reprezentującego niepodpisany operator przesunięcia prawego, powiązanie dynamiczne dla operatora >>> nie będzie obsługiwane, a powiązanie statyczne i dynamiczne (§12.3) zostanie dostosowane, aby to odzwierciedlić.
Wady
Alternatywy
Drzewa wyrażeń Linq
Operator >>> będzie obsługiwany w drzewach wyrażeń Linq.
- W przypadku operatora zdefiniowanego przez użytkownika zostanie utworzony węzeł BinaryExpression wskazujący metodę operatora.
- Dla wstępnie zdefiniowanych operatorów
- gdy pierwszy operand jest typem bez znaku, zostanie utworzony węzeł typu BinaryExpression.
- gdy pierwszy operand jest typem ze znakiem, zostanie dodana konwersja pierwszego operandu na typ bez znaku, zostanie utworzony węzeł BinaryExpression i zostanie dodana konwersja wyniku z powrotem do typu ze znakiem.
Na przykład:
Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)
Resolution:
Odrzucono, zobacz https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator, aby uzyskać więcej informacji.
Nierozwiązane pytania
Spotkania projektowe
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications