Delen via


Rekenkundige operatoren (C#-verwijzing)

De volgende operators voeren rekenkundige bewerkingen uit met operanden van numerieke typen:

Deze operators worden ondersteund door alle integrale en drijvende komma numerieke typen.

In het geval van integrale typen worden deze operators (met uitzondering van de ++ en -- operators) gedefinieerd voor de int, uinten longulong typen. Wanneer operanden van andere integrale typen zijn (sbyte, byte, short, ushortof char), worden hun waarden geconverteerd naar het int type, wat ook het resultaattype van een bewerking is. Wanneer operanden van verschillende integrale of zwevende kommatypen zijn, worden hun waarden geconverteerd naar het dichtstbijzijnde type, als een dergelijk type bestaat. Zie de sectie Numerieke promoties van de C#-taalspecificatie voor meer informatie. De ++ operatoren worden -- gedefinieerd voor alle integrale en drijvendekommagenumerieke typen en het tekentype . Het resultaattype van een samengestelde toewijzingsexpressie is het type van de linkeroperand.

Operator incrementeel ++

Met de unaire increment-operator ++ wordt de operand met 1 verhoogd. De operand moet een variabele, een eigenschapstoegang of een indexeerfunctietoegang zijn.

De increment-operator wordt ondersteund in twee formulieren: de operator voor het verhogen van het voorvoegsel en x++de operator voor het verhogen van voorvoegsels. ++x

Operator voor incrementele postfix

Het resultaat x++ is de waarde van x vóór de bewerking, zoals in het volgende voorbeeld wordt weergegeven:

int i = 3;
Console.WriteLine(i);   // output: 3
Console.WriteLine(i++); // output: 3
Console.WriteLine(i);   // output: 4

Operator voor incrementeel voorvoegsel

Het resultaat is ++x de waarde van x na de bewerking, zoals in het volgende voorbeeld wordt weergegeven:

double a = 1.5;
Console.WriteLine(a);   // output: 1.5
Console.WriteLine(++a); // output: 2.5
Console.WriteLine(a);   // output: 2.5

Operator voor afschalingsbewerking --

De unaire degradatieoperator -- ontneemt de operand door 1. De operand moet een variabele, een eigenschapstoegang of een indexeerfunctietoegang zijn.

De operator voor verlagen wordt ondersteund in twee vormen: de operator voor het verlagen van het voorvoegsel, x--en de operator voor het verlagen van voorvoegsels, --x.

Operator voor het verlagen van postfix

Het resultaat x-- is de waarde van x vóór de bewerking, zoals in het volgende voorbeeld wordt weergegeven:

int i = 3;
Console.WriteLine(i);   // output: 3
Console.WriteLine(i--); // output: 3
Console.WriteLine(i);   // output: 2

Operator voor het verlagen van voorvoegsel

Het resultaat is --x de waarde van x na de bewerking, zoals in het volgende voorbeeld wordt weergegeven:

double a = 1.5;
Console.WriteLine(a);   // output: 1.5
Console.WriteLine(--a); // output: 0.5
Console.WriteLine(a);   // output: 0.5

Unaire plus- en mintekenoperators

De unaire + operator retourneert de waarde van de operand. De unaire - operator berekent de numerieke negatie van de 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

Het ulong-type biedt geen ondersteuning voor de unaire - operator.

Vermenigvuldigingsoperator *

De vermenigvuldigingsoperator * berekent het product van de operanden:

Console.WriteLine(5 * 2);         // output: 10
Console.WriteLine(0.5 * 2.5);     // output: 1.25
Console.WriteLine(0.1m * 23.4m);  // output: 2.34

De unaire * operator is de operator voor indirectie van de aanwijzer.

Afdelingsoperator /

De divisieoperator / verdeelt de linkeroperand door de rechteroperand.

Deling van gehele getallen

Voor de operanden van gehele getallen is het resultaat van de / operator van een geheel getaltype en is het quotiënt van de twee operanden afgerond op nul:

Console.WriteLine(13 / 5);    // output: 2
Console.WriteLine(-13 / 5);   // output: -2
Console.WriteLine(13 / -5);   // output: -2
Console.WriteLine(-13 / -5);  // output: 2

Als u het quotiënt van de twee operanden wilt verkrijgen als een drijvendekommagetal, gebruikt u de float, doubleof decimal het type:

Console.WriteLine(13 / 5.0);       // output: 2.6

int a = 13;
int b = 5;
Console.WriteLine((double)a / b);  // output: 2.6

Deling van drijvende komma

Voor de float, doubleen decimal typen is het resultaat van de / operator het quotiënt van de twee operanden:

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

Als een van de operanden isdecimal, kan een andere operand noch noch doublefloat , omdat noch float double impliciet converteerbaar is naar decimal. U moet de float of double operand expliciet converteren naar het decimal type. Zie Ingebouwde numerieke conversies voor meer informatie over conversies tussen numerieke typen.

Restoperatorpercentage

De restoperator % berekent de rest na het delen van de linkeroperand door de rechteroperand.

Restgetal geheel getal

Voor de operanden van gehele getallen is het resultaat a % b de waarde die wordt geproduceerd door a - (a / b) * b. Het teken van de rest zonder nul is hetzelfde als het teken van de linkeroperand, zoals in het volgende voorbeeld wordt weergegeven:

Console.WriteLine(5 % 4);   // output: 1
Console.WriteLine(5 % -4);  // output: 1
Console.WriteLine(-5 % 4);  // output: -1
Console.WriteLine(-5 % -4); // output: -1

Gebruik de Math.DivRem methode om zowel gehele getallen als restresultaten te berekenen.

Rest van drijvende komma

Voor de float en double operanden, het resultaat van x % y voor de eindige x en y is de waarde z zodanig dat

  • Het teken van z, indien niet-nul, is hetzelfde als het teken van x.
  • De absolute waarde van z is de waarde die wordt geproduceerd door |x| - n * |y| waar n het grootst mogelijke gehele getal is dat kleiner is dan of gelijk is aan |x| / |y| en |x| |y| de absolute waarden zijn van x respectievelijk y.

Notitie

Deze methode voor het berekenen van de rest is vergelijkbaar met de methode die wordt gebruikt voor gehele getallen, maar verschilt van de IEEE 754-specificatie. Als u de restbewerking nodig hebt die voldoet aan de IEEE 754-specificatie, gebruikt u de Math.IEEERemainder methode.

Zie de sectie Restoperator van de C#-taalspecificatie voor informatie over het gedrag van de % operator met niet-eindige operanden.

Voor de decimal operanden is de restoperator % gelijk aan de restoperator van het System.Decimal type.

In het volgende voorbeeld ziet u het gedrag van de restoperator met operanden met drijvende komma:

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

Operator voor optellen +

De opteloperator + berekent de som van de operanden:

Console.WriteLine(5 + 4);       // output: 9
Console.WriteLine(5 + 4.3);     // output: 9.3
Console.WriteLine(5.1m + 4.2m); // output: 9.3

U kunt de + operator ook gebruiken voor tekenreekssamenvoeging en combinatie van gemachtigden. Zie het + artikel en += operators voor meer informatie.

Operator voor aftrekken -

De aftrekkingsoperator - trekt de rechteroperand af van de linkeroperand:

Console.WriteLine(47 - 3);      // output: 44
Console.WriteLine(5 - 4.3);     // output: 0.7
Console.WriteLine(7.5m - 2.3m); // output: 5.2

U kunt de operator ook gebruiken voor het - verwijderen van gemachtigden. Zie het - artikel en -= operators voor meer informatie.

Samengestelde toewijzing

Voor een binaire operator op, een samengestelde toewijzingsexpressie van het formulier

x op= y

is gelijk aan

x = x op y

behalve dat dit x slechts eenmaal wordt geëvalueerd.

In het volgende voorbeeld ziet u het gebruik van samengestelde toewijzingen met rekenkundige operatoren:

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

Vanwege numerieke promoties is het resultaat van de op bewerking mogelijk niet impliciet converteerbaar naar het type T x. In dat geval op is een vooraf gedefinieerde operator en het resultaat van de bewerking expliciet converteerbaar naar het type T x, is een samengestelde toewijzingsexpressie van het formulier x op= y gelijk aan x = (T)(x op y), behalve dat het x slechts eenmaal wordt geëvalueerd. In het volgende voorbeeld ziet u dat gedrag:

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

In het voorgaande voorbeeld is de waarde 44 het resultaat van het converteren van waarde 300 naar het byte type.

Notitie

In de gecontroleerd overloopcontrolecontext genereert het voorgaande voorbeeld een OverflowException. Zie de sectie Integer-rekenkundige overloop voor meer informatie.

U gebruikt ook de += en -= operators om zich respectievelijk te abonneren op en af te melden voor een gebeurtenis. Zie Hoe u zich kunt abonneren op en afmelden voor gebeurtenissen voor meer informatie.

Operatorprioriteit en associativiteit

In de volgende lijst worden rekenkundige operatoren gesorteerd die beginnen met de hoogste prioriteit tot het laagste:

  • Operatoren voor incrementeel x++ en verlagen van postfix x--
  • Voorvoegsel verhogen ++x en verlagen --x en unaire + en - operatoren
  • Vermenigvuldigings- *en /% operatoren
  • Additief + en - operators

Binaire rekenkundige operatoren zijn links-associatief. Dat wil gezegd dat operators met hetzelfde prioriteitsniveau van links naar rechts worden geëvalueerd.

Gebruik haakjes, ()om de volgorde van evaluatie te wijzigen die wordt opgelegd door de prioriteit van de operator en associativiteit.

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

Zie de sectie Operatorprioriteit van het artikel C#-operators voor de volledige lijst met C#-operators die zijn gerangschikt op prioriteitsniveau.

Rekenkundige overloop en deling door nul

Wanneer het resultaat van een rekenkundige bewerking buiten het bereik van mogelijke eindige waarden van het betrokken numerieke type valt, is het gedrag van een rekenkundige operator afhankelijk van het type operanden.

Rekenkundige overloop geheel getal

Deling van gehele getallen door nul gooit altijd een DivideByZeroException.

Als een rekenkundige overloop van gehele getallen optreedt, bepaalt de context voor overloopcontrole, die kan worden gecontroleerd of uitgeschakeld, het resulterende gedrag:

  • Als er in een gecontroleerde context een overloop plaatsvindt in een constante expressie, treedt er een compilatietijdfout op. Als de bewerking tijdens runtime wordt uitgevoerd, wordt er anders een OverflowException gegenereerd.
  • In een niet-gecontroleerd context wordt het resultaat afgekapt door alle bits in hoge volgorde te verwijderen die niet in het doeltype passen.

Naast de ingeschakelde en niet-gecontroleerde instructies kunt u de checked en unchecked operators gebruiken om de context voor overloopcontrole te beheren, waarin een expressie wordt geëvalueerd:

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}.");
}

Rekenkundige bewerkingen worden standaard uitgevoerd in een niet-gecontroleerd context.

Rekenkundige overloop met drijvende komma

Rekenkundige bewerkingen met de float en double typen genereren nooit een uitzondering. Het resultaat van rekenkundige bewerkingen met deze typen kan een van de speciale waarden zijn die oneindig en niet-een-getal vertegenwoordigen:

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

Voor de operanden van het decimal type gooit rekenkundige overloop altijd een OverflowException. Delen door nul gooit altijd een DivideByZeroException.

Afrondingsfouten

Vanwege algemene beperkingen van de drijvende-kommaweergave van reële getallen en rekenkundige drijvende komma kunnen er afrondingsfouten optreden in berekeningen met drijvende-kommatypen. Dat wil gezegd, het geproduceerde resultaat van een expressie kan afwijken van het verwachte wiskundige resultaat. In het volgende voorbeeld ziet u een aantal van deze gevallen:

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

Zie opmerkingen op de referentiepagina's System.Double, System.Single of System.Decimal voor meer informatie.

Overbelasting van operatoren

Een door de gebruiker gedefinieerd type kan de rekenkundige operatoren unaire (++, --, +, en ) en -binaire operatoren (*, /%, +, en -) overbelasten. Wanneer een binaire operator overbelast is, wordt de bijbehorende operator voor samengestelde toewijzing ook impliciet overbelast. Een door de gebruiker gedefinieerd type kan een samengestelde toewijzingsoperator niet expliciet overbelasten.

Door de gebruiker gedefinieerde gecontroleerde operators

Vanaf C# 11 kunt u, wanneer u een rekenkundige operator overbelast, het checked trefwoord gebruiken om de gecontroleerde versie van die operator te definiëren. In het volgende voorbeeld ziet u hoe u dit doet:

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);
    }
}

Wanneer u een ingeschakelde operator definieert, moet u ook de bijbehorende operator definiëren zonder de checked wijzigingsfunctie. De ingeschakelde operator wordt aangeroepen in een gecontroleerde context. De operator zonder de checked wijzigingsfunctie wordt aangeroepen in een niet-gecontroleerde context. Als u alleen de operator zonder modifier checked opgeeft, wordt deze in zowel een als een checked unchecked context aangeroepen.

Wanneer u beide versies van een operator definieert, wordt verwacht dat hun gedrag alleen verschilt wanneer het resultaat van een bewerking te groot is om het resultaattype als volgt weer te geven:

  • Een gecontroleerde operator gooit een OverflowException.
  • Een operator zonder de checked wijzigingsfunctie retourneert een exemplaar dat een afgekapt resultaat vertegenwoordigt.

Zie voor informatie over het verschil in gedrag van de ingebouwde rekenkundige operatoren de rekenkundige overloop en deling door nulsectie .

U kunt de checked wijzigingsfunctie alleen gebruiken wanneer u een van de volgende operators overbelast:

Notitie

De context voor overloopcontrole binnen de hoofdtekst van een gecontroleerde operator wordt niet beïnvloed door de aanwezigheid van de checked wijzigingsfunctie. De standaardcontext wordt gedefinieerd door de waarde van de optie CheckForOverflowUnderflow Compiler. Gebruik de checked en unchecked instructies om expliciet de context voor overloopcontrole op te geven, zoals het voorbeeld aan het begin van deze sectie laat zien.

C#-taalspecificatie

Zie de volgende secties van de C#-taalspecificatie voor meer informatie:

Zie ook