Osignerad höger skiftoperator
Not
Den här artikeln är en funktionsspecifikation. Specifikationen fungerar som designdokument för funktionen. Den innehåller föreslagna specifikationsändringar, tillsammans med information som behövs under utformningen och utvecklingen av funktionen. Dessa artiklar publiceras tills de föreslagna specifikationsändringarna har slutförts och införlivats i den aktuella ECMA-specifikationen.
Det kan finnas vissa skillnader mellan funktionsspecifikationen och den slutförda implementeringen. Dessa skillnader samlas in i de relevanta anteckningarna från LDM (Language Design Meeting) .
Du kan läsa mer om processen för att införa funktionsspecifikationer i C#-språkstandarden i artikeln om specifikationerna.
Sammanfattning
En osignerad högerflytt-operator kommer att stödjas av C# både som en inbyggd operator (för primitiva integraltyper) och som en användardefinierad operator.
Motivation
När du arbetar med signerat integralvärde är det inte ovanligt att du behöver flytta bitar rätt utan att replikera den höga orderbiten på varje skift. Även om detta kan uppnås för primära integraltyper med en vanlig skiftoperator, krävs en konvertering till en osignerad typ före skiftoperationen och en konvertering tillbaka efteråt. Inom ramen för de allmänna matematiska gränssnitt som biblioteken planerar att exponera är detta potentiellt mer problematiskt eftersom typen kanske inte behöver ha en osignerad motsvarighet definierad eller känd i förväg av den allmänna matematiska koden, men en algoritm kan förlita sig på möjligheten att utföra en osignerad rätt skiftåtgärd.
Detaljerad design
Operatorer och skiljetecken
Avsnitt §6.4.6 justeras för att inkludera >>>
operator – den osignerade höger skiftoperatören:
unsigned_right_shift
: '>>>'
;
unsigned_right_shift_assignment
: '>>>='
;
Inga tecken av något slag (inte ens blanksteg) tillåts mellan token i unsigned_right_shift och unsigned_right_shift_assignment produktioner. Dessa produktioner behandlas särskilt för att möjliggöra korrekt hantering av type_parameter_lists.
Skiftoperatorer
Avsnitt §12.11 justeras för att inkludera >>>
operator – den osignerade högerskiftoperatorn:
Operatorerna <<
, >>
och >>>
används för att utföra bitväxlingsåtgärder.
shift_expression
: additive_expression
| shift_expression '<<' additive_expression
| shift_expression right_shift additive_expression
| shift_expression unsigned_right_shift additive_expression
;
För en åtgärd av formuläret x << count
eller x >> count
eller x >>> count
tillämpas binär operatoröverbelastningsmatchning (§12.4.5) för att välja en specifik operatorimplementering. Operanderna konverteras till parametertyperna för den valda operatorn och typen av resultat är operatorns returtyp.
De fördefinierade osignerade skiftoperatorerna har stöd för samma uppsättning signaturer som fördefinierade signerade skiftoperatorer stöder i dag i den aktuella implementeringen.
Skift höger:
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);
Operatorn
>>>
skiftarx
rätt med ett antal bitar som beräknas enligt beskrivningen nedan.Lågordningsbitarna i
x
ignoreras, de återstående bitarna flyttas åt höger och de tomma bitpositionerna i hög ordning är inställda på noll.
För de fördefinierade operatorerna beräknas antalet bitar som ska flyttas enligt följande:
- När typen av
x
ärint
elleruint
, bestäms skiftantalet av de fem bitarna med lägre ordning icount
. Med andra ord beräknas skiftantalet fråncount & 0x1F
. - När typen av
x
ärlong
ellerulong
bestäms skiftantalet av de lägre sex bitarna avcount
. Med andra ord beräknas skiftantalet fråncount & 0x3F
.
Om det resulterande skiftantalet är noll returnerar skiftoperatorerna helt enkelt värdet för x
.
Skiftåtgärder orsakar aldrig spill och ger samma resultat i checked
och unchecked
kontexter.
Tilldelningsoperatorer
Avsnitt §12.21 justeras för att inkludera unsigned_right_shift_assignment enligt följande:
assignment_operator
: '='
| '+='
| '-='
| '*='
| '/='
| '%='
| '&='
| '|='
| '^='
| '<<='
| right_shift_assignment
| unsigned_right_shift_assignment
;
Integraltyper
Integraltyperna §8.3.6 avsnitt justeras för att inkludera information om >>>
operatör. Den relevanta punktpunkten är följande:
- För operatorerna binary
<<
,>>
och>>>
konverteras den vänstra operanden till typT
, därT
är den första avint
,uint
,long
ochulong
som helt kan representera alla möjliga värden för operand. Åtgärden utförs sedan med hjälp av precisionen av typenT
, och typen av resultat ärT
.
Konstanta uttryck
Operatorn >>>
läggs till i den uppsättning konstruktioner som tillåts i konstanta uttryck §12.23.
Operatörsöverlagring
Operatorn >>>
läggs till i uppsättningen överlagrbara binära operatorer på §12.4.3.
Upplyfta operatorer
Operatorn >>>
kommer att läggas till i uppsättningen av binära operatorer som tillåter en höjd form vid §12.4.8.
Operatorprioritet och associativitet
Avsnitt §12.4.2 justeras för att lägga till operatören >>>
i kategorin "Skift" och operatören >>>=
i kategorin "Tilldelning och lambda-uttryck".
Grammatiktydligheter
Den >>>
operatorn är föremål för samma grammatik tvetydigheter som en vanlig operator, som beskrivs i >>
.
Operatörer
Avsnittet §15.10 kommer att justeras för att inkludera operatören >>>
.
overloadable_binary_operator
: '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '<<'
| right_shift | unsigned_right_shift | '==' | '!=' | '>' | '<' | '>=' | '<='
;
Binära operatorer
Underskriften av en >>>
operatör omfattas av samma regler som de på §15.10.3 för underskrift av en >>
operatör.
Metadatanamn
Avsnitt "I.10.3.2 Binära operatorer" för ECMA-335 har redan reserverat namnet på en icke-tecknad högerskiftoperator – op_UnsignedRightShift.
Linq-uttrycksträd
Operatorn >>>
stöds inte i Linq Expression Trees eftersom semantik för fördefinierade >>>
operatorer på signerade typer inte kan representeras korrekt utan att konverteringar läggs till i en osignerad typ och tillbaka. Mer information finns i https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.
Dynamisk bindning
Det verkar som om dynamisk bindning använder värden av System.Linq.Expressions.ExpressionType-enum för att kommunicera vilken typ av binär operator det rör sig om till körningstidsbindaren. Eftersom vi inte har någon medlem som specifikt representerar en högerförskjutningsoperator utan tecken, kommer dynamisk bindning för >>>
-operatorn inte att stödjas och den statiska och dynamiska bindningen (§12.3) kommer att justeras för att återspegla detta.
Nackdelar
Alternativ
Linq-uttrycksträd
Operatorn >>>
stöds i Linq Expressioin Trees.
- För en användardefinierad operator skapas en BinaryExpression-nod som pekar på operatormetoden.
- För fördefinierade operatorer
- När den första operanden är en ansignerad typ skapas en BinaryExpression-nod.
- När den första operanden är en signerad typ läggs en konvertering för den första operanden till en osignerad typ, en BinaryExpression-nod skapas och konvertering för resultatet tillbaka till den signerade typen läggs till.
Till exempel:
Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)
Resolution:
Avvisad, se https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator för ytterligare information.
Olösta frågor
Designa möten
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications