Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Följande operatorer utför aritmetiska åtgärder med operander av numeriska typer:
- Unary
++(increment),--(decrement),+(plus), och-(minus) operatorer - Binära
*operatorer (multiplikation),/(division),%(rest),+(addition)och-(subtraktion)
Alla numeriska typer av integraler och flyttalser stöder dessa operatorer.
Typerna int, uint, longoch ulong definierar alla dessa operatorer. De andra integraltyperna (sbyte, byte, short, ushortoch char) definierar endast operatorerna ++ och -- . Om du använder integraltyperna sbyte, , byte, short, ushorteller char som operander för de andra operatorerna konverteras värdena till int typen och resultattypen är int. Om operanderna är olika integral- eller flyttalstyper konverteras deras värden till den närmaste innehållande typen, om en sådan typ finns. Mer information finns i avsnittet Numeriska kampanjer i C#-språkspecifikationen. Operatorerna ++ och -- definieras för alla numeriska typer av integraler och flyttalstyper och teckentypen . Resultattypen för ett sammansatt tilldelningsuttryck är typen av den vänstra operanden.
C#-språkreferensen dokumenterar den senaste versionen av C#-språket. Den innehåller även inledande dokumentation för funktioner i offentliga förhandsversioner för den kommande språkversionen.
Dokumentationen identifierar alla funktioner som först introducerades i de tre senaste versionerna av språket eller i aktuella offentliga förhandsversioner.
Tips/Råd
Information om när en funktion först introducerades i C# finns i artikeln om språkversionshistoriken för C#.
Inkrementsoperator ++
Den oföränderliga inkrementsoperatorn ++ ökar sin operande med 1. Operand måste vara en variabel, en egenskapsåtkomst eller en indexerare .
Inkrementsoperatorn stöds i två former: postfix-inkrementsoperatorn , x++och prefixet increment operator, ++x.
Postfix-inkrementsoperator
Resultatet av x++ är värdet xför före åtgärden, som följande exempel visar:
int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i++); // output: 3
Console.WriteLine(i); // output: 4
Inkrementsoperator för prefix
Resultatet av ++x är värdet xför efter åtgärden, som följande exempel visar:
double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(++a); // output: 2.5
Console.WriteLine(a); // output: 2.5
Decrement-operatorn --
Den unary decrementoperatorn -- decrements dess operand vid 1. Operand måste vara en variabel, en egenskapsåtkomst eller en indexerare .
Decrementoperatorn är tillgänglig i två former: postfixdeprevalensoperatorn , x--och prefixets decrementoperator, --x.
Postfix-decrementoperator
Resultatet av x-- är värdet xför före åtgärden, som följande exempel visar:
int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i--); // output: 3
Console.WriteLine(i); // output: 2
Prefixdeprevalensoperator
Resultatet av --x är värdet xför efter åtgärden, som följande exempel visar:
double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(--a); // output: 0.5
Console.WriteLine(a); // output: 0.5
Unary plus- och minusoperatorer
Den unary + operatorn returnerar värdet för dess operand. Den unary - operatorn beräknar den numeriska negationen av dess operand.
Console.WriteLine(+4); // output: 4
Console.WriteLine(-4); // output: -4
Console.WriteLine(-(-4)); // output: 4
uint a = 5;
var b = -a;
Console.WriteLine(b); // output: -5
Console.WriteLine(b.GetType()); // output: System.Int64
Console.WriteLine(-double.NaN); // output: NaN
Typen ulong stöder inte unary-operatorn - .
Multiplikationsoperator *
Multiplikationsoperatorn * beräknar produkten av sina operander:
Console.WriteLine(5 * 2); // output: 10
Console.WriteLine(0.5 * 2.5); // output: 1.25
Console.WriteLine(0.1m * 23.4m); // output: 2.34
Unary-operatorn * är pekarens indirekta operator.
Divisionsoperator/
Divisionsoperatorn / delar sin vänstra operande med sin högra operande.
Heltalsdivision
För operander av heltalstyper är resultatet av operatorn / av heltalstyp och är lika med kvoten för de två operanderna avrundade mot noll:
Console.WriteLine(13 / 5); // output: 2
Console.WriteLine(-13 / 5); // output: -2
Console.WriteLine(13 / -5); // output: -2
Console.WriteLine(-13 / -5); // output: 2
Om du vill hämta kvoten för de två operanderna som ett flyttalsnummer använder du floattypen , doubleeller decimal :
Console.WriteLine(13 / 5.0); // output: 2.6
int a = 13;
int b = 5;
Console.WriteLine((double)a / b); // output: 2.6
Flyttalsdelning
För typerna float, doubleoch decimal returnerar operatorn / kvoten för de två operanderna:
Console.WriteLine(16.8f / 4.1f); // output: 4.097561
Console.WriteLine(16.8d / 4.1d); // output: 4.09756097560976
Console.WriteLine(16.8m / 4.1m); // output: 4.0975609756097560975609756098
Om en operand är decimalkan den andra operanden inte vara float eller double, eftersom varken float eller double har en implicit konvertering till decimal. Du måste uttryckligen float konvertera eller double operand till decimal typen . Mer information om konverteringar mellan numeriska typer finns i Inbyggda numeriska konverteringar.
Restoperator %
Restoperatorn % beräknar resten efter att ha delat sin vänstra operande med sin högra operande.
Heltalsrester
För operander av heltalstyper är resultatet av a % b värdet som genereras av $a - \frac{a}{b} \times b$. Tecknet för resten som inte är noll matchar tecknet för den vänstra operanden, som följande exempel visar:
Console.WriteLine(5 % 4); // output: 1
Console.WriteLine(5 % -4); // output: 1
Console.WriteLine(-5 % 4); // output: -1
Console.WriteLine(-5 % -4); // output: -1
Math.DivRem Använd metoden för att beräkna både heltalsdivision och restresultat.
Flyttalsrester
float För operanderna och double är resultatet av x % y för det ändliga x och y det värde z som
- Tecknet för
z, om det inte är noll, matchar tecknet förx. - Det absoluta värdet
zför kommer från beräkningen $|x| - n \times |y|$, därnär det största heltalet mindre än eller lika med $\frac{|x|}{|y|}$. Här representerar $|x|$ och $|y|$ de absoluta värdenaxföryrespektive .
Kommentar
Den här metoden för beräkning av resten liknar den metod som används för heltalsoperor, men den skiljer sig från IEEE 754-specifikationen. Om du behöver reståtgärden som uppfyller IEEE 754-specifikationen Math.IEEERemainder använder du metoden.
Information om beteendet för operatorn % med icke-ändliga operander finns i avsnittet Restoperator i C#-språkspecifikationen.
För decimal operander fungerar restoperatorn % på samma sätt som resten av typens System.Decimal operator.
I följande exempel visas hur restoperatorn beter sig med flyttalsoperatorer:
Console.WriteLine(-5.2f % 2.0f); // output: -1.2
Console.WriteLine(5.9 % 3.1); // output: 2.8
Console.WriteLine(5.9m % 3.1m); // output: 2.8
Additionsoperator +
Additionsoperatorn + beräknar summan av sina operander:
Console.WriteLine(5 + 4); // output: 9
Console.WriteLine(5 + 4.3); // output: 9.3
Console.WriteLine(5.1m + 4.2m); // output: 9.3
Du kan också använda operatorn + för kombination av strängsammanfogning och ombud. Mer information finns i artikeln operatorer + och .+=
Subtraktionsoperator –
Subtraktionsoperatorn - subtraherar den högra operanden från den vänstra operanden:
Console.WriteLine(47 - 3); // output: 44
Console.WriteLine(5 - 4.3); // output: 0.7
Console.WriteLine(7.5m - 2.3m); // output: 5.2
Du kan också använda operatorn - för att ta bort ett ombud. Mer information finns i operatorerna- och-=.
Sammansatt tilldelning
För en binär operator op, ett sammansatt tilldelningsuttryck för formuläret
x op= y
Motsvarar
x = x op y
Förutom att x bara utvärderas en gång.
I följande exempel visas användningen av sammansatt tilldelning med aritmetiska operatorer:
int a = 5;
a += 9;
Console.WriteLine(a); // output: 14
a -= 4;
Console.WriteLine(a); // output: 10
a *= 2;
Console.WriteLine(a); // output: 20
a /= 4;
Console.WriteLine(a); // output: 5
a %= 3;
Console.WriteLine(a); // output: 2
På grund av numeriska kampanjer kanske resultatet av op åtgärden inte implicit kan konverteras till typen Tx. I ett sådant fall, om op är en fördefinierad operator och resultatet av åtgärden uttryckligen kan konverteras till typen T av x, är ett sammansatt tilldelningsuttryck av formuläret x op= y likvärdigt med x = (T)(x op y), förutom att endast x utvärderas en gång. Följande exempel visar det beteendet:
byte a = 200;
byte b = 100;
var c = a + b;
Console.WriteLine(c.GetType()); // output: System.Int32
Console.WriteLine(c); // output: 300
a += b;
Console.WriteLine(a); // output: 44
I föregående exempel är värdet 44 resultatet av att konvertera värdet 300 till byte typen.
Kommentar
I den markerade överflödeskontrollkontexten genererar föregående exempel en OverflowException. Mer information finns i avsnittet Heltalsaritmiskt spill .
Du använder också operatorerna += och -= för att prenumerera på och avbryta prenumerationen på en händelse. Mer information finns i Så här prenumererar du på och avbryter prenumerationen på händelser.
Operatorprioritet och associativitet
Följande lista beställer aritmetiska operatorer från högsta prioritet till lägsta prioritet:
- Operatorer för inkrement
x++och minskning avx--postfix - Prefix för inkrements
++x---xoch deskrementsoperatorer samt unary+- och-operatorer - Multiplicativa
*operatorer ,/och% - Additiva
+och-operatorer
Binära aritmetiska operatorer är vänster-associativa. Kompilatorn utvärderar operatorer med samma prioritetsnivå från vänster till höger.
Använd parenteser, (), för att ändra ordningen på utvärderingen som har införts av operatorprioritet och associativitet.
Console.WriteLine(2 + 2 * 2); // output: 6
Console.WriteLine((2 + 2) * 2); // output: 8
Console.WriteLine(9 / 5 / 2); // output: 0
Console.WriteLine(9 / (5 / 2)); // output: 4
En fullständig lista över C#-operatorer ordnade efter prioritetsnivå finns i avsnittet Operatorprioriteten i artikeln C#-operatorer .
Aritmetiskt spill och division med noll
När resultatet av en aritmetikåtgärd ligger utanför intervallet för möjliga ändliga värden av den berörda numeriska typen beror beteendet för en aritmetikoperator på typen av dess operander.
Heltalsaritmetiskt spill
Heltalsdivision med noll genererar alltid en DivideByZeroException.
Om heltals-aritmetiskt spill inträffar styr överflödeskontrollkontexten, som kan kontrolleras eller avmarkeras, det resulterande beteendet:
- I en markerad kontext uppstår ett kompileringsfel om spill inträffar i ett konstant uttryck. Annars genereras en OverflowException när åtgärden utförs vid körning.
- I en omarkerad kontext trunkeras resultatet genom att alla bitar i hög ordning som inte får plats i måltypen ignoreras.
Kommentar
Heltalsdivisionen har ett specialfall där en ArithmeticException kan kastas även i en omarkerad kontext. När den vänstra operanden är det minsta värdet för en signerad heltalstyp (int.MinValue eller long.MinValue) och den högra operanden är -1, kan resultatet inte representeras i måltypen. .NET-körningen genererar en ArithmeticException i det här fallet, som du ser i följande exempel:
int a = int.MinValue;
int b = -1;
try
{
int c = unchecked(a / b);
}
catch (ArithmeticException)
{
Console.WriteLine($"Overflow occurred when dividing {a} by {b}.");
}
Tillsammans med de markerade och omarkerade uttrycken kan du använda operatorerna checked och unchecked för att styra överflödeskontrollkontexten, där ett uttryck utvärderas:
int a = int.MaxValue;
int b = 3;
Console.WriteLine(unchecked(a + b)); // output: -2147483646
try
{
int d = checked(a + b);
}
catch(OverflowException)
{
Console.WriteLine($"Overflow occurred when adding {a} to {b}.");
}
Som standard utförs aritmetiska åtgärder i en omarkerad kontext.
Flyttalsaritmetiskt spill
Aritmetiska åtgärder med hjälp av typerna float och double utlöser aldrig ett undantag. Resultatet av aritmetiska åtgärder som använder dessa typer kan vara ett av specialvärden som representerar oändligheten och inte ett tal:
double a = 1.0 / 0.0;
Console.WriteLine(a); // output: Infinity
Console.WriteLine(double.IsInfinity(a)); // output: True
Console.WriteLine(double.MaxValue + double.MaxValue); // output: Infinity
double b = 0.0 / 0.0;
Console.WriteLine(b); // output: NaN
Console.WriteLine(double.IsNaN(b)); // output: True
För typens operander decimal genererar aritmetiskt spill alltid ett OverflowException. Division med noll genererar alltid en DivideByZeroException.
Avrundningsfel
På grund av allmänna begränsningar i flyttalsrepresentationen av verkliga tal och flyttalsaritmetik kan avrundningsfel inträffa i beräkningar som använder flyttalstyper. Resultatet av ett uttryck kan skilja sig från det förväntade matematiska resultatet. I följande exempel visas flera sådana fall:
Console.WriteLine(.41f % .2f); // output: 0.00999999
double a = 0.1;
double b = 3 * a;
Console.WriteLine(b == 0.3); // output: False
Console.WriteLine(b - 0.3); // output: 5.55111512312578E-17
decimal c = 1 / 3.0m;
decimal d = 3 * c;
Console.WriteLine(d == 1.0m); // output: False
Console.WriteLine(d); // output: 0.9999999999999999999999999999
Mer information finns i kommentarerna på referenssidorna System.Double, System.Single eller System.Decimal .
Överlagring av operator
Du kan överbelasta de oföränderliga (++, --, +och -) och binära (*, , /%, +och -) aritmetiska operatorerna för en användardefinierad typ. När du överbelastar en binär operator överbelastar du även implicit motsvarande sammansatta tilldelningsoperator. Från och med C# 14 kan en användardefinierad typ uttryckligen överbelasta de sammansatta tilldelningsoperatorerna (op=) för att tillhandahålla en effektivare implementering. Vanligtvis överbelastar en typ dessa operatorer eftersom värdet kan uppdateras på plats, i stället för att allokera en ny instans för att lagra resultatet av åtgärden. Om en typ inte ger någon explicit överlagring genererar kompilatorn den implicita överbelastningen.
Användardefinierade kontrollerade operatorer
När du överbelastar en aritmetikoperator kan du använda nyckelordet checked för att definiera den kontrollerade versionen av operatorn. I följande exempel visas hur du gör det:
public record struct Point(int X, int Y)
{
public static Point operator checked +(Point left, Point right)
{
checked
{
return new Point(left.X + right.X, left.Y + right.Y);
}
}
public static Point operator +(Point left, Point right)
{
return new Point(left.X + right.X, left.Y + right.Y);
}
}
När du definierar en kontrollerad operator måste du också definiera motsvarande operator utan checked modifieraren. En markerad kontext anropar den kontrollerade operatorn och en omarkerad kontext anropar operatorn utan checked modifieraren.
När du definierar båda versionerna av en operator skiljer sig deras beteende bara när resultatet av en åtgärd är för stort för att representera i resultattypen enligt följande:
- En kontrollerad operator genererar en OverflowException.
- En operator utan
checkedmodifieraren returnerar en instans som representerar ett trunkerat resultat.
Information om skillnaden i beteende för de inbyggda aritmetiska operatorerna finns i avsnittet Aritmetiskt spill och division efter noll .
Du kan bara använda checked modifieraren när du överbelastar någon av följande operatorer:
- Unary
++,--och-operatorer - Binära
*operatorer ,/,+och-operatorer - Operatorer för sammansatt tilldelning
*=,/=,+=och-=(C# 14 och senare) - Explicita konverteringsoperatorer
Kommentar
Modifieraren checked påverkar inte överflödeskontrollkontexten i dess brödtext. Standardkontexten definieras av värdet för kompileringsalternativet CheckForOverflowUnderflow .
checked och unchecked för att uttryckligen ange kontexten för spillkontroll, som exemplet i början av det här avsnittet visar.
Språkspecifikation för C#
Mer information finns i följande avsnitt i C#-språkspecifikationen:
- Operatorer för inkrement och minskning av postfix
- Operatorer för inkrement och minskning av prefix
- Unary plus-operator
- Unär minusoperator
- Multiplikationsoperator
- Divisionsoperator
- Restoperator
- Additionsoperator
- Subtraktionsoperator
- Sammansatt tilldelning
- De markerade och avmarkerade operatorerna
- Numeriska kampanjer
- Användardefinierad sammansatt tilldelning