Aritmetiska operatorer (C#-referens)
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)
Dessa operatorer stöds av alla numeriska typer av integrerad och flyttal .
När det gäller integraltyper definieras dessa operatorer (förutom operatorerna ++
och --
) för typerna int
, uint
, long
och ulong
. När operander är av andra integraltyper (sbyte
, , short
byte
, ushort
eller char
), konverteras deras värden till int
typen, vilket också är resultattypen för en åtgärd. När operander har olika typer av integraler eller flyttal 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.
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 x
fö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 x
fö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 stöds i två former: postfixdeprevalensoperatorn , x--
och prefixets decrementoperator, --x
.
Postfix-decrementoperator
Resultatet av x--
är värdet x
fö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 x
fö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 float
typen , double
eller 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
, double
och decimal
är resultatet av 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 av operanderna är decimal
kan en annan operande varken float
vara eller double
, eftersom varken float
eller double
implicit kan konverteras 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 - (a / b) * b
. Tecknet för resten som inte är noll är detsamma som 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, är samma som tecknet förx
. - Det absoluta värdet
z
för är det värde som genereras av|x| - n * |y|
varn
är det största möjliga heltalet som är mindre än eller lika med|x| / |y|
och|x|
och|y|
är de absoluta värdenax
för respektivey
.
Kommentar
Den här metoden för beräkning av resten motsvarar den som används för heltalsoperor, men 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.
decimal
För operanderna motsvarar restoperatorn %
resten av System.Decimal typens operator.
I följande exempel visas beteendet för restoperatorn 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 sin högra operande från sin vänstra operande:
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 borttagning av -
ombud. Mer information finns i artikeln operatorer -
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
endast 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 T
x
. 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 med början från den högsta prioriteten till den lägsta:
- Operatorer för inkrement
x++
och minskning avx--
postfix - Inkrement
++x
och dementering--x
av prefix samt unary+
och-
operatorer - Multiplicativa
*
operatorer ,/
och%
- Additiva
+
och-
operatorer
Binära aritmetiska operatorer är vänster-associativa. Operatorer med samma prioritetsnivå utvärderas 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.
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 typerna float
och double
utlöser aldrig ett undantag. Resultatet av aritmetiska åtgärder med 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 med flyttalstyper. Det innebär att det producerade 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 kommentarer på referenssidorna System.Double, System.Single eller System.Decimal .
Överlagring av operator
En användardefinierad typ kan överbelasta de oföränderliga (++
, , --
+
och -
) och binära (*
, , %
/
, +
och -
) aritmetiska operatorerna. När en binär operator är överbelastad överbelastas även motsvarande sammansatta tilldelningsoperator implicit. En användardefinierad typ kan inte uttryckligen överbelasta en sammansatt tilldelningsoperator.
Användardefinierade kontrollerade operatorer
Från och med C# 11 kan du använda nyckelordet checked
för att definiera den kontrollerade versionen av operatorn när du överbelastar en aritmetikoperator. 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. Den kontrollerade operatorn anropas i en kontrollerad kontext. Operatorn utan checked
modifieraren anropas i en omarkerad kontext. Om du bara anger operatorn utan checked
modifieraren anropas den i både en checked
och unchecked
kontext.
När du definierar båda versionerna av en operator förväntas deras beteende bara skilja sig 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
checked
modifieraren 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 - Explicita konverteringsoperatorer
Kommentar
Överflödeskontrollkontexten i en kontrollerad operators brödtext påverkas inte av förekomsten av checked
modifieraren. Standardkontexten definieras av värdet för kompileringsalternativet CheckForOverflowUnderflow . checked
Använd -instruktionerna 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
- Unary minus operator
- Multiplikationsoperator
- Divisionsoperator
- Restoperator
- Additionsoperator
- Subtraktionsoperator
- Sammansatt tilldelning
- De markerade och avmarkerade operatorerna
- Numeriska kampanjer