Operátor posunu doprava bez znaménka
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách schůzky návrhu jazyka (LDM).
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Shrnutí
Operátor posunu vpravo bez znaménka bude C# podporován jako zabudovaný operátor (pro základní celočíselné typy) a jako uživatelsky definovaný operátor.
Motivace
Při práci s podepsanou celočíselnou hodnotou není neobvyklé, že budete potřebovat posunout bity doprava, aniž byste při každém posunu replikovali nejvyšší bit. I když toho lze dosáhnout u primitivních celočíselných typů pomocí běžného operátoru posunu, je před operací posunu a po ní nutné přetypování na nepodepsaný typ a zpět. V kontextu obecných matematických rozhraní, která knihovny hodlají zpřístupnit, může být potenciálně problematičtější, že typ nemusí mít nutně definovaný nebo známý předem ekvivalent bez znaménka, ale algoritmus může spoléhat na schopnost provádět operaci posunu doprava bez znaménka.
Podrobný návrh
Operátory a interpunkční znaky
Oddíl §6.4.6 bude upraven tak, aby zahrnoval operátor >>>
- operátor posunu doprava bez znaménka:
unsigned_right_shift
: '>>>'
;
unsigned_right_shift_assignment
: '>>>='
;
Mezi tokeny v produkcích unsigned_right_shift a unsigned_right_shift_assignment nejsou povoleny žádné znaky jakéhokoli druhu, včetně mezer. Tyto výroby jsou zpracovávány speciálně, aby bylo možné správně zpracovávat type_parameter_lists.
Operátory posunu
Oddíl §12.11 se upraví tak, aby zahrnoval operátor >>>
- operátor posunu doprava bez znaménka:
Operátory <<
, >>
a >>>
slouží k provádění operací posunu bitů.
shift_expression
: additive_expression
| shift_expression '<<' additive_expression
| shift_expression right_shift additive_expression
| shift_expression unsigned_right_shift additive_expression
;
Pro operaci formuláře x << count
nebo x >> count
nebo x >>> count
, rozlišení přetížení binárního operátoru (§12.4.5) se použije k výběru konkrétní implementace operátoru. Operandy jsou převedeny na typy parametrů vybraného operátoru a typ výsledku je návratový typ operátoru.
Předdefinované operátory posunu bez znaménka budou podporovat stejnou sadu podpisů, které v aktuální implementaci podporují předdefinované operátory posunu se znaménky.
Posunout doprava:
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);
Operátor
>>>
posunex
doprava o počet bitů vypočítaný podle níže uvedeného popisu.Bity
x
s nízkým pořadím se zahodí, zbývající bity se posunou doprava a pozice prázdných bitů s vysokým pořadím se nastaví na nulu.
U předdefinovaných operátorů se počet bitů, které se mají posunout, vypočítá takto:
- Pokud je typ
x
int
nebouint
, počet posunů je určen nižšími pěti bitycount
. Jinými slovy, počet směn se vypočítá zcount & 0x1F
. - Pokud je typ
x
long
neboulong
, počet posunů je dán šesti nejnižšími bitycount
. Jinými slovy, počet směn se vypočítá zcount & 0x3F
.
Pokud je výsledný počet směn nula, operátory směn jednoduše vrátí hodnotu x
.
Posunovací operace nikdy nezpůsobí přetečení a produkují stejné výsledky v checked
a unchecked
kontekstech.
Operátory přiřazení
Oddíl §12.21 bude upraven tak, aby zahrnoval unsigned_right_shift_assignment následujícím způsobem:
assignment_operator
: '='
| '+='
| '-='
| '*='
| '/='
| '%='
| '&='
| '|='
| '^='
| '<<='
| right_shift_assignment
| unsigned_right_shift_assignment
;
Celočíselné typy
Oddíl integrálních typů §8.3.6 se upraví, aby zahrnoval informace o operátoru >>>
. Příslušná odrážka je následující:
- Pro binární
<<
,>>
a>>>
operátory je levý operand převeden na typT
, kdeT
je první zint
,uint
,long
aulong
, které mohou plně představovat všechny možné hodnoty operandu. Operace se pak provádí pomocí přesnosti typuT
a typ výsledku jeT
.
Konstantní výrazy
Operátor >>>
bude přidán do sady konstruktorů povolených v konstantních výrazech v §12.23.
Přetížení operátoru
Operátor >>>
bude přidán do sady přetížitelných binárních operátorů v §12.4.3.
Povýšené operátory
Operátor >>>
bude přidán do sady binárních operátorů, které umožňují zvednutí formuláře v §12.4.8.
Priorita operátorů a asociativita
Oddíl §12.4.2 se upraví tak, aby do kategorie Shift přidal operátor >>>
a operátor >>>=
do kategorie Přiřazení a výraz lambda.
Gramatické nejednoznačnosti
Operátor >>>
podléhá stejným gramatickým nejednoznačnostem popsaným v §6.2.5 jako běžný operátor >>
.
Operátoři
Oddíl §15.10 se upraví tak, aby zahrnoval operátor >>>
.
overloadable_binary_operator
: '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '<<'
| right_shift | unsigned_right_shift | '==' | '!=' | '>' | '<' | '>=' | '<='
;
Binární operátory
Podpis operátora >>>
podléhá stejným pravidlům jako v §15.10.3 pro podpis operátora >>
.
Název metadat
Oddíl I.10.3.2 Binární operátory ECMA-335 již rezervoval název operátoru posunu doprava bez znaménka – op_UnsignedRightShift.
Linq stromy výrazů
Operátor >>>
nebude podporován v stromech výrazů Linq, protože sémantika předdefinovaných operátorů >>>
u podepsaných typů nemůže být přesně reprezentována bez přidání převodů na nepodepsaný typ a zpět. Další informace najdete v tématu https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.
Dynamická vazba
Vypadá to, že dynamické vazby používají hodnoty System.Linq.Expressions.ExpressionType výčtu ke komunikaci typu binárního operátoru s pořadačem modulu runtime. Vzhledem k tomu, že nemáme člena, který specificky reprezentuje operátor posunu doprava bez znaménka, dynamická vazba pro operátor >>>
nebude podporována a oddíl o statické a dynamické vazbě (§12.3) bude upraven tak, aby tuto skutečnost zohlednil.
Nevýhody
Alternativy
Linq stromy výrazů
Operátor >>>
bude podporován v LINQ Expression Trees.
- U uživatelem definovaného operátoru se vytvoří uzel BinaryExpression odkazující na metodu operátoru.
- Pro předdefinované operátory
- Pokud je prvním operandem přiřazený typ, vytvoří se uzel BinaryExpression.
- když je prvním operandem podepsaný typ, přidá se převod prvního operandu na nepodepsaný typ, vytvoří se uzel BinaryExpression a převod výsledku zpět na podepsaný typ se přidá.
Například:
Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)
Resolution:
Zamítnuto, další informace najdete v tématu https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.
Nevyřešené otázky
Schůzky o designu
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications