Share via


Rekenkundige operatoren (C#-verwijzing)

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

Alle integrale en numerieke typen drijvende komma ondersteunen deze operators.

De inttypen , uintlongen ulong typen definiëren al deze operators. De andere integrale typen (sbyte, byte, short, ushorten char) definiëren alleen de ++ en -- operators. Als u voor de andere operators de integrale typen sbyte, byte, shortof ushortchar als operanden gebruikt, worden de waarden geconverteerd naar het int type en het resultaattype .int Als de operanden verschillende integrale of zwevende kommatypen zijn, worden de 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.

De C#-taalreferentiedocumenten beschrijven de meest recent uitgebrachte versie van de C#-taal. Het bevat ook de eerste documentatie voor functies in openbare previews voor de aanstaande taalrelease.

De documentatie identificeert alle functies die voor het eerst zijn geïntroduceerd in de laatste drie versies van de taal of in de huidige openbare previews.

Aanbeveling

Raadpleeg het artikel over de versiegeschiedenis van de C#-taal om te achterhalen wanneer een functie voor het eerst is geïntroduceerd in C#.

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 xvóó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 xna 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 is beschikbaar in twee formulieren: de operator voor het verlagen van het voorvoegsel, x--en de operator voor het verlagen van het voorvoegsel, --x.

Operator voor het verlagen van postfix

Het resultaat x-- is de waarde van xvóó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 xna 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 ophalen 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 floatoperator , doubleen decimal typen, retourneert 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 de ene operand isdecimal, kan de andere operand niet zijn float of double, omdat noch doublefloat een impliciete conversie 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 operanden van gehele getallen is het resultaat a % b de waarde die wordt geproduceerd door $a - \frac{a}{b} \times b$. Het teken van de rest zonder nul komt overeen met 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, komt overeen met het teken van x.
  • De absolute waarde van z de berekening $|x| - n \times |y|$, waarbij n het grootste gehele getal kleiner dan of gelijk is aan $\frac{|x|}{|y|}$. Hier vertegenwoordigen $|x|$ en $|y|$ de absolute waarden 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 % voor informatie over het gedrag van de operator met niet-eindige operanden.

Voor decimal operanden werkt de operator voor rest % hetzelfde als de restoperator van het System.Decimal type.

In het volgende voorbeeld ziet u hoe de restoperator zich gedraagt 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 om een gemachtigde te verwijderen. Zie de - 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 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 Tx. In dat geval op is een vooraf gedefinieerde operator en het resultaat van de bewerking expliciet converteerbaar naar het type Tx, 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 van hoogste prioriteit tot laagste prioriteit gesorteerd:

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

Binaire rekenkundige operatoren zijn links-associatief. Dat wil gezegd, de compiler evalueert operators met hetzelfde prioriteitsniveau van links naar rechts.

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.

Notitie

Deling van gehele getallen heeft een speciaal geval waarbij een ArithmeticException kan worden gegenereerd, zelfs in een niet-gecontroleerd context. Wanneer de linkeroperand de minimumwaarde is van een ondertekend geheel getal (int.MinValue of long.MinValue) en de rechteroperand is -1, kan het resultaat niet worden weergegeven in het doeltype. De .NET-runtime genereert een ArithmeticException in dit geval, zoals wordt weergegeven in het volgende voorbeeld:

int a = int.MinValue;
int b = -1;
try
{
    int c = unchecked(a / b);
}
catch (ArithmeticException)
{
    Console.WriteLine($"Overflow occurred when dividing {a} by {b}.");
}

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 behulp van de float typen double genereren nooit een uitzondering. Het resultaat van rekenkundige bewerkingen die deze typen gebruiken, 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 in de drijvende-kommaweergave van reële getallen en rekenkundige drijvende komma kunnen afrondingsfouten optreden in berekeningen die gebruikmaken van drijvende-kommatypen. Het 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 de opmerkingen op de referentiepagina's System.Double, System.Single of System.Decimal voor meer informatie.

Overbelasting van operatoren

U kunt de unaire (, --, +en ) en -binaire operatoren (*++, /%, , +en -) rekenkundige operatoren voor een door de gebruiker gedefinieerd type overbelasten. Wanneer u een binaire operator overbelast, overbelast u ook impliciet de bijbehorende samengestelde toewijzingsoperator. Vanaf C# 14 kan een door de gebruiker gedefinieerd type expliciet de operators voor samengestelde toewijzingen (op=) overbelasten om een efficiëntere implementatie te bieden. Normaal gesproken overbelastt een type deze operators omdat de waarde kan worden bijgewerkt in plaats van een nieuw exemplaar toe te wijzen om het resultaat van de bewerking op te slaan. Als een type geen expliciete overbelasting biedt, genereert de compiler de impliciete overbelasting.

Door de gebruiker gedefinieerde gecontroleerde operators

Wanneer u een rekenkundige operator overbelast, kunt u 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. Een gecontroleerde context roept de gecontroleerde operator aan en een niet-gecontroleerde context roept de operator aan zonder de checked wijzigingsfunctie.

Wanneer u beide versies van een operator definieert, verschilt het gedrag alleen 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:

  • Unaire ++, --en - operators
  • Binaire*, /, en +- operatoren
  • Samengestelde toewijzing *=, /=, +=, en -= operators (C# 14 en hoger)
  • Expliciete conversieoperators

Notitie

De checked wijzigingsfunctie heeft geen invloed op de context van overloopcontrole binnen de hoofdtekst. 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