Megosztás:


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.

A int, uint, longés ulong típus határozza meg ezeket az operátorokat. A többi integráltípus (sbyte, byte, short, ushort, és char) csak az ++ és -- operátorokat határozza meg. A többi operátor esetében, ha az integráltípusokat sbyte, byte, short, ushortvagy char operandusokat használja, a rendszer az értékeket a int típusra konvertálja, az eredmény típusa pedig az int. Ha az operandusok különböző integrál- vagy lebegőpontos típusok, akkor 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.

A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.

A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.

Jótanács

Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.

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 érhető el: 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

floatA , doubleés decimal a típusok esetében az / operátor a két operandus hányadosát adja vissza:

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, a másik operandus nem lehet float vagy doublenem lehet, mert sem implicit módon nem floatdouble konvertálható decimal. Az operandusokat vagy az operandusokat float explicit módon kell a típusra konvertálnidouble.decimal 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

Egész típusú operandusok esetén az eredmény a % b a $a - \frac{a}{b} \times b$ által előállított érték. A nem nulla maradék jele megegyezik a bal oldali operandus jelével, ahogy az alábbi példa is 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 double véges x % y eredmény, és x az az érték yz, amely

  • A ( ha nem nulla) előjele zmegegyezik a következő jelével x: .
  • Az abszolút érték z az $|x| - n \times |y|$ számításból származik, ahol n a legnagyobb egész szám kisebb vagy egyenlő, mint $\frac{|x|}{|y|}$. Itt a $|x|$ és a $|y|$ az és a , illetve yaz abszolút értékeket x jelöli.

Feljegyzés

Ez a számítási módszer hasonló az egész szám operandusokhoz használt módszerhez, 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.

Operandusok esetén decimal a fennmaradó operátor % ugyanúgy működik, mint a System.Decimal típus többi operátora.

Az alábbi példa bemutatja, hogy a fennmaradó operátor hogyan viselkedik lebegőpontos operandusokkal:

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 + szóló += cikket.

Kivonási operátor –

A kivonási operátor - kivonja a jobb oldali operandust 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átorral - is eltávolíthat egy meghatalmazottat. További információ: az operátorok és -= az- operátorok.

Összetett hozzárendelés

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

x op= y

Egyenértékű azzal, hogy

x = x op y

Kivéve, hogy a x csak egyszer lesz 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 nem konvertálható implicit módon a típusra Tx. Ilyen esetben, ha op egy előre definiált operátor, és a művelet eredménye explicit módon átalakítható a típusraTx, 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 aritmetikai operátorokat rendel a legmagasabb prioritástól a legalacsonyabb prioritásig:

  • Postfix-növekményx++- és decrement operátorok x--
  • Előtag növekményes ++x és decrement --x operátorok, valamint 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. Ez azt jelzi, hogy a fordító balról jobbra ugyanazt a elsőbbséget élvező operátorokat értékeli ki.

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.

Feljegyzés

Az egész számok osztásának van egy speciális esete, ahol egy ArithmeticException nem ellenőrzött környezetben is eldobhatók. Ha a bal operandus egy aláírt egész szám (int.MinValue vagy long.MinValue) minimális értéke, és a jobb operandus az -1, az eredmény nem jeleníthető meg a céltípusban. A .NET-futtatókörnyezet ebben az esetben a ArithmeticException következő példában látható:

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

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

Az aritmetikai műveletek és double a float típusok használatával soha nem ad kivételt. Az ilyen típusokat használó aritmetikai műveletek eredménye lehet egy olyan különleges érték, amely a végtelent és a nem-a-számot jelöli:

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ípusokat használó számításokban. Egy kifejezés 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ípushoz túlterhelheti a unáris (++, --, , +és -) és bináris (*, /, , %és +-) aritmetikai operátorokat. Bináris operátor túlterhelése esetén implicit módon túlterheli a megfelelő összetett hozzárendelési operátort is. A C# 14-től kezdve a felhasználó által definiált típus explicit módon túlterhelheti az összetett hozzárendelési operátorokat (op=) a hatékonyabb végrehajtás érdekében. Egy típus általában túlterheli ezeket az operátorokat, mert az érték frissíthető a helyén, ahelyett, hogy egy új példányt helyez ki a művelet eredményének tárolására. Ha egy típus nem biztosít explicit túlterhelést, a fordító implicit túlterhelést hoz létre.

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

Ha 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 . Egy ellenőrzött környezet meghívja az ellenőrzött operátort, a nem ellenőrzött környezet pedig a módosító nélkül hívja meg az operátort checked .

Ha egy operátor mindkét verzióját definiálja, azok viselkedése csak akkor különbözik, ha egy művelet eredménye túl nagy ahhoz, hogy az eredménytípusban az alábbiak szerint legyen jelölve:

  • 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:

  • Unary ++, --és - operátorok
  • Bináris *, /, +és - operátorok
  • Összetett hozzárendelés *=, /=és +=-= operátorok (C# 14 és újabb)
  • Explicit konverziós operátorok

Feljegyzés

A checked módosító nem befolyásolja a szervezeten belüli túlcsordulás-ellenőrzési környezetet. Az alapértelmezett környezetet a CheckForOverflowUnderflow fordítóbeállítás értéke határozza meg. Az és checked az unchecked 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