Megosztás a következőn keresztül:


Számtani operátorok (C#-referencia)

A következő operátorok numerikus típusú operandusokkal hajtanak végre aritmetikai műveleteket:

Ezeket az operátorokat minden integrál és lebegőpontos numerikus típus támogatja.

Az integráltípusok esetében ezek az operátorok (kivéve az és az ++ operátorok) a , uint, longés ulong a inttípusok esetében vannak meghatározva--. Ha az operandusok más integrál típusúak (sbyte, byte, , short, ushortvagy char), az értékek a típusra int lesznek konvertálva, ami szintén egy művelet eredménytípusa. Ha az operandusok különböző integrál- vagy lebegőpontos típusok, az értékek a legközelebbi tartalmazó típusra lesznek konvertálva, ha létezik ilyen típus. További információkért tekintse meg a C#-nyelv specifikációjának Numerikus promóciók szakaszát. Az ++ és -- az operátorok az összes integrál és lebegőpontos numerikus típushoz és a karaktertípushoz vannak definiálva. Az összetett hozzárendelési kifejezés eredménytípusa a bal oldali operandus típusa.

Növekmény operátor ++

A nem növekményes operátor ++ 1-zel növeli az operandusát. Az operandusnak változónak, tulajdonsághozzáférésnek vagy indexelő hozzáférésnek kell lennie.

A növekményes operátor két formában támogatott: a postfix növekmény operátor és x++az előtag növekmény operátora. ++x

Postfix növekmény operátor

Ennek eredménye x++ a művelet előtti érték x , ahogyan az alábbi példa is mutatja:

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

Előtag-növekmény operátora

Ennek eredménye ++x a művelet utáni érték x , ahogyan az alábbi példa is mutatja:

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

Decrement operátor -

A nem a decrement operátor -- 1-gyel dekrementeli az operandusát. Az operandusnak változónak, tulajdonsághozzáférésnek vagy indexelő hozzáférésnek kell lennie.

A decrement operátor két formában támogatott: a postfix decrement operátor és x--az előtag decrement operátor --x.

Postfix decrement operátor

Ennek eredménye x-- a művelet előtti érték x , ahogyan az alábbi példa is mutatja:

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

Előtag decrement operátora

Ennek eredménye --x a művelet utáni érték x , ahogyan az alábbi példa is mutatja:

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

Unary plusz és mínusz operátorok

A unary + operátor az operandus értékét adja vissza. A unary - operátor kiszámítja az operandus numerikus negációját.

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

Az ulong típus nem támogatja a nem kívánt operátort - .

Szorzási operátor *

A szorzási operátor * kiszámítja az operandusok szorzatát:

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

A unary * operátor a mutató indirekt operátora.

Osztás operátor /

Az osztás operátor / a bal oldali operandusát a jobb oldali operandussal osztja el.

Egész szám osztása

Az egész szám típusú operandusok esetében az / operátor eredménye egész szám típusú, és a két operandus hányadosát nullára kerekíti:

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

A két operandus hányadosának lebegőpontos számként való lekéréséhez használja az , doublevagy decimal írja be a floatkövetkezőt:

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

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

Lebegőpontos osztás

A float, doubleés decimal típusok esetében az / operátor eredménye a két operandus hányadosa:

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

Ha az egyik operandus az decimal, egy másik operandus sem lehet, float sem double, mert sem implicit módon nem float double konvertálható decimal. Az operandusokat vagy az operandusokat float explicit módon kell a típusra konvertálnidecimal.double A numerikus típusok közötti átalakításokkal kapcsolatos további információkért lásd a beépített numerikus átalakításokat.

Fennmaradó operátor %

A maradék operátor % kiszámítja a maradékot, miután elosztja a bal oldali operandusát a jobb oldali operandussal.

Egész szám fennmaradó része

Az egész szám típusú operandusok esetében az eredmény a % b a a - (a / b) * b. A nem nulla maradék jele megegyezik a bal oldali operandus jelével, ahogyan az alábbi példa mutatja:

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

A metódus használatával Math.DivRem kiszámíthatja az egész és a fennmaradó eredményeket is.

Lebegőpontos maradék

Az és az float operandusok esetében a x % y véges x eredmény, és y az az érték z double, amely

  • A (ha nem nulla) előjele zmegegyezik a jelével x.
  • Az abszolút érték z az az érték, amelyet |x| - n * |y| a legnagyobb n lehetséges egész szám állít elő, amely kisebb vagy egyenlő |x| |x| / |y|, és |y| az és yaz abszolút értékex.

Feljegyzés

Ez a számítási módszer hasonló az egész szám operandusokhoz használthoz, de eltér az IEEE 754 specifikációjától. Ha az IEEE 754 specifikációnak megfelelő fennmaradó műveletre van szüksége, használja a Math.IEEERemainder módszert.

A nem véges operandusokkal rendelkező operátor viselkedéséről % a C# nyelvi specifikációJának Fennmaradó operátor szakaszában olvashat.

Az decimal operandusok esetében a maradék operátor % egyenértékű a típus többi operátorávalSystem.Decimal.

Az alábbi példa a fennmaradó operátor lebegőpontos operandusokkal való viselkedését mutatja be:

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

Összeadás operátor +

Az összeadási operátor + kiszámítja az operandusok összegét:

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

Az operátort sztringösszefűzéshez + és delegálási kombinációhoz is használhatja. További információkért tekintse meg az + operátorokról szóló += cikket.

Kivonási operátor –

A kivonási operátor - kivonja a jobb oldali operandusát a bal oldali operandusból:

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

Az operátort - a delegálás eltávolításához is használhatja. További információkért tekintse meg az - operátorokról szóló -= cikket.

Összetett hozzárendelés

Bináris operátor opesetén az űrlap összetett hozzárendelési kifejezése

x op= y

egyenértékű a

x = x op y

kivéve, hogy csak x egyszer van kiértékelve.

Az alábbi példa az összetett hozzárendelés aritmetikai operátorokkal való használatát mutatja be:

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

Numerikus előléptetések miatt előfordulhat, hogy a op művelet eredménye implicit módon nem konvertálható a típusra T x. Ilyen esetben, ha op egy előre definiált operátor, és a művelet eredménye explicit módon átalakítható a típusraxT, az űrlap x op= y összetett hozzárendelési kifejezése egyenértékűx = (T)(x op y), kivéve, ha x csak egyszer lesz kiértékelve. Az alábbi példa ezt a viselkedést mutatja be:

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

Az előző példában az érték 44 az érték 300 típussá byte alakításának eredménye.

Az eseményre való feliratkozáshoz és az eseményről való leiratkozáshoz az operátorok és -= az operátorok is használhatók+=. További információ: Hogyan iratkozhat fel és iratkozhat le az eseményekről.

Operátorok elsőbbsége és asszociativitása

Az alábbi lista a számtani operátorokat a legmagasabb prioritástól a legalacsonyabbig rendeli:

  • Postfix-növekményx++- és decrement operátorok x--
  • Előtag növekménye ++x és csökkentése --x , unary + és - operátorok
  • Többszörös *, /és % operátorok
  • Additív + és - operátorok

A bináris aritmetikai operátorok bal asszociatívak. Vagyis az azonos előzményszinttel rendelkező operátorok kiértékelése balról jobbra történik.

Zárójelek ()használatával módosíthatja az operátorok elsőbbsége és az asszociativitás által előírt kiértékelési sorrendet.

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

A C#-operátorok elsőbbségi szint szerint rendezett teljes listájáért tekintse meg a C# operátorok cikkének Operátorok elsőbbsége című szakaszát.

Aritmetikai túlcsordulás és osztás nullával

Ha egy aritmetikai művelet eredménye kívül esik az érintett numerikus típus lehetséges véges értékeinek tartományán, az aritmetikai operátor viselkedése az operandusok típusától függ.

Egész számtani túlcsordulás

Az egész szám nullával való osztása mindig a DivideByZeroException.

Egész számtani túlcsordulás esetén a túlcsordulás-ellenőrző környezet, amely ellenőrizhető vagy nem ellenőrizhető, szabályozza az eredményül kapott viselkedést:

  • Ha egy ellenőrzött környezetben túlcsordulás történik egy állandó kifejezésben, fordítási időhiba lép fel. Ellenkező esetben, ha a műveletet futásidőben hajtják végre, a rendszer egy OverflowException dobásra kerül.
  • A nem bejelölt környezetben a rendszer csonkolja az eredményt úgy, hogy elveti a céltípusba nem illő, nagy megrendelésű biteket.

Az ellenőrzött és a nem ellenőrzött utasítások mellett az checked operátorokkal unchecked szabályozhatja a túlcsordulás-ellenőrzési környezetet, amelyben egy kifejezés kiértékelése történik:

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

Alapértelmezés szerint az aritmetikai műveletek nem ellenőrzött környezetben történnek.

Lebegőpontos aritmetikai túlcsordulás

A számtani műveletek és double a float típusok soha nem kivételt képeznek. Az ilyen típusú aritmetikai műveletek eredménye lehet a végtelent és a nem-a-számot jelképező különleges értékek egyike:

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

A típus operandusai esetében az decimal aritmetikai túlcsordulás mindig egy OverflowException. A nullával való osztás mindig a DivideByZeroException.

Kerekítési hibák

A valós számok lebegőpontos ábrázolásának általános korlátozásai és a lebegőpontos aritmetika miatt kerekítési hibák fordulhatnak elő a lebegőpontos típusú számításokban. Ez azt jelenti, hogy egy kifejezés előállított eredménye eltérhet a várt matematikai eredménytől. Az alábbi példa számos ilyen esetet mutat be:

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

További információt a System.Double, a System.Single vagy a System.Decimális referenciaoldalon talál.

Operátorok túlterhelése

A felhasználó által definiált típus túlterhelheti a unáris (++, , --, +és -) és bináris (*, /, , %, +és -) aritmetikai operátorokat. Ha egy bináris operátor túlterhelt, a megfelelő összetett hozzárendelési operátor is implicit módon túlterhelt. A felhasználó által definiált típus nem tudja explicit módon túlterhelni az összetett hozzárendelési operátorokat.

Felhasználó által megadott ellenőrzött operátorok

A C# 11-től kezdve, amikor túlterhel egy számtani operátort, a checked kulcsszóval meghatározhatja az operátor ellenőrzött verzióját. Az alábbi példa bemutatja, hogyan teheti ezt meg:

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

Ha bejelölt operátort határoz meg, a módosító nélkül is meg kell határoznia a megfelelő operátort checked . Az ellenőrzött operátor egy ellenőrzött környezetben van meghívva; a checked módosító nélküli operátort a rendszer nem ellenőrzött környezetben hívja meg. Ha csak a módosító nélkül adja meg az checked operátort, a rendszer mind a checked unchecked környezetben, mind a környezetben meghívja azt.

Ha egy operátor mindkét verzióját definiálja, akkor várható, hogy a viselkedésük csak akkor tér el, ha egy művelet eredménye túl nagy ahhoz, hogy az eredménytípust az alábbiak szerint jelölje:

  • Egy ellenőrzött operátor egy OverflowException.
  • A módosító nélküli checked operátor egy csonkolt eredményt képviselő példányt ad vissza.

A beépített aritmetikai operátorok viselkedésének különbségéről az Aritmetikai túlcsordulás és a nulladik szakasz szerinti osztás című témakörben olvashat bővebben.

A módosító csak akkor használható checked , ha a következő operátorok bármelyikét túlterheli:

Feljegyzés

Az ellenőrzött operátor törzsén belüli túlcsordulás-ellenőrzési környezetet a módosító jelenléte checked nem befolyásolja. Az alapértelmezett környezetet a CheckForOverflowUnderflow fordítóbeállítás értéke határozza meg. Az és unchecked az checked utasítások segítségével explicit módon megadhatja a túlcsordulás-ellenőrzési környezetet, ahogyan azt a szakasz elején látható példa is mutatja.

C# nyelvspecifikáció

További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:

Lásd még