Sdílet prostřednictvím


Aritmetické operátory (referenční dokumentace jazyka C#)

Následující operátory provádějí aritmetické operace s operandy číselných typů:

Tyto operátory podporují všechny numerické typy integrálních a typů s plovoucí desetinnou čárkou.

Typy int, uint, long a ulong definují všechny tyto operátory. Ostatní integrální typy (sbyte, byte, short, ushort a char) definují pouze operátory ++ a --. U jiných operátorů jsou operandy celočíselné typy sbyte, , byteshort, ushort, nebo char, jejich hodnoty jsou převedeny na int typ a typ výsledku je int. Pokud jsou operandy různých integrálních typů nebo typů s plovoucí desetinou čárkou, jejich hodnoty se převedou na nejbližší typ obsahující, pokud takový typ existuje. Další informace najdete v části Číselné povýšení specifikace jazyka C#. Operátory ++ a operátory jsou definovány pro všechny celočíselné a číselné typy s plovoucí desetinou čárkou a typ znaku--. Typ výsledku výrazu složeného přiřazení je typ levého operandu.

Operátor přírůstku ++

Unární operátor ++ přírůstku zvýší svůj operand o 1. Operand musí být proměnná, přístup k vlastnosti nebo přístup indexeru.

Operátor přírůstku je podporován ve dvou formách: operátor x++přírůstku přípony a operátor přírůstku předpony, ++x.

Příponový operátor inkrementace

Výsledek x++ je hodnota xpřed operací, jak ukazuje následující příklad:

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

Operátor přírůstku předpony

Výsledek ++x je hodnota xza operací, jak ukazuje následující příklad:

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

Operátor dekrementace --

Unární -- dekrement operátor dekrementuje svůj operand o 1. Operand musí být proměnná, přístup k vlastnosti nebo přístup indexeru.

Operátor dekrementu je podporován ve dvou formách: operátor x--dekrementace přípony a operátor dekrementace předpony . --x

Příponový operátor dekrementace

Výsledek x-- je hodnota xpřed operací, jak ukazuje následující příklad:

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

Operátor dekrementace předpony

Výsledek --x je hodnota xza operací, jak ukazuje následující příklad:

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

Unární operátory plus a minus

Unární + operátor vrátí hodnotu svého operandu. Unární - operátor vypočítá číselnou negaci svého operandu.

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

Typ ulong nepodporuje unární - operátor.

Operátor násobení *

Operátor * násobení vypočítá součin svých operandů:

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

Unární * operátor je operátor nepřímého ukazatele.

Operátor dělení /

Operátor / dělení rozdělí operand na levé straně jeho operandem zprava.

Celočíselné dělení

U operandů celočíselného typu je výsledkem / operátoru celočíselného typu a rovná se podílu dvou operandů zaokrouhlených na nulu:

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

Chcete-li získat podíl dvou operandů jako číslo s plovoucí desetinou čárkou, použijte floathodnotu , doublenebo decimal zadejte:

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

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

Dělení s plovoucí desetinou čárkou

floatPro operátor , doublea decimal typy je výsledek / operátoru podíl dvou operandů:

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

Pokud je jeden z operandů decimal, jiný operand nemůže být float ani double, protože ani není floatdouble implicitně konvertibilní na decimal. Musíte explicitně převést float nebo double operand na decimal typ. Další informace o převodech mezi číselnými typy naleznete v tématu Předdefinované číselné převody.

Operátor zbytku %

Operátor zbytku % vypočítá zbytek po vydělení levého operandu jeho operandem zprava.

Zbytek celého čísla

Pro operandy celočíselného typu je výsledkem a % b hodnoty, kterou a - (a / b) * bvytváří . Znaménko nenulového zbytku je stejné jako znaménko levého operandu, jak ukazuje následující příklad:

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

Použijte metodu Math.DivRem k výpočtu celočíselného dělení i výsledků zbytku.

Zbytek s plovoucí desetinou čárkou

float U operandů a double operandů je výsledek x % y konečné xy hodnoty, která je taková, z že

  • Znaménko z, pokud není nula, je stejné jako znaménko x.
  • Absolutní hodnota je hodnota z vytvořená tam, kde |x| - n * |y|n je největší možné celé číslo, které je menší než nebo rovno |x| / |y| a |x| jsou |y| absolutními hodnotami x a yv uvedeném pořadí.

Poznámka:

Tato metoda výpočtu zbytku je podobná metodě použité pro celočíselné operandy, ale liší se od specifikace IEEE 754. Pokud potřebujete zbývající operaci, která splňuje specifikaci IEEE 754, použijte metodu Math.IEEERemainder .

Informace o chování operátoru % s nekonficiálními operandy naleznete v části Operátor zbytku specifikace jazyka C#.

decimal U operandů je operátor % zbytku ekvivalentní operátoru zbytku System.Decimal typu.

Následující příklad ukazuje chování operátoru zbytku s operandy s plovoucí desetinou čárkou:

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

Operátor sčítání +

Operátor sčítání + vypočítá součet svých operandů:

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

Operátor můžete použít + také pro zřetězení řetězců a kombinaci delegátů. Další informace najdete v + článku a += operátory .

Operátor odčítání –

Operátor - odčítání odečte svůj operand z levého operandu:

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

Operátor můžete také použít k odebrání delegáta - . Další informace najdete v - článku a -= operátory .

Složené přiřazení

U binárního operátoru opje složený výraz přiřazení formuláře.

x op= y

Je ekvivalentní

x = x op y

Kromě toho, že x se vyhodnotí jenom jednou.

Následující příklad ukazuje použití složeného přiřazení s aritmetických operátorů:

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

Z důvodu číselných povýšení nemusí být výsledek operace implicitně konvertibilní na typ opT.x V takovém případě je-li op předdefinovaný operátor a výsledek operace je explicitně konvertibilní na typ Tx , složený výraz přiřazení formuláře x op= y je ekvivalentní x = (T)(x op y), s výjimkou toho, že x je vyhodnocen pouze jednou. Následující příklad ukazuje toto chování:

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

V předchozím příkladu je výsledkem 44 převodu hodnoty 300 na byte typ.

Poznámka:

V kontextu kontroly přetečení vyvolá předchozí příklad chybu OverflowException. Další informace najdete v části aritmetické přetečení celého čísla.

Operátory a += operátory -= také používáte k přihlášení k odběru a odhlášení odběru události. Další informace najdete v tématu Jak se přihlásit k odběru a odhlásit odběr událostí.

Priorita operátorů a asociativita

Následující seznam obsahuje aritmetické operátory počínaje nejvyšší prioritou až po nejnižší:

  • Operátory přírůstku a dekrementace x++x-- přípony
  • Inkrementace a dekrementace ++x--x předpony a unární + operátory a - operátory
  • Multiplikativní *, /a % operátory
  • Sčítání + a - operátory

Binární aritmetické operátory jsou asociativní zleva. To znamená, že operátory se stejnou úrovní priority se vyhodnocují zleva doprava.

Pomocí závorek ()změňte pořadí vyhodnocení uloženého podle priority operátoru a asociativity.

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

Úplný seznam operátorů jazyka C# seřazených podle úrovně priority najdete v části Priorita operátorů v článku operátory jazyka C#.

Aritmetické přetečení a dělení nulou

Pokud je výsledek aritmetické operace mimo rozsah možných konečných hodnot zahrnutého číselného typu, chování aritmetického operátoru závisí na typu jeho operandů.

Celočíselná aritmetická přetečení

Celočíselné dělení nulou vždy vyvolá DivideByZeroExceptionhodnotu .

Pokud dojde k aritmetickému přetečení celého čísla, řídí výsledný chování kontext kontroly přetečení, který lze zkontrolovat nebo zrušit zaškrtnutím tohoto políčka:

  • Pokud v kontrolovaném kontextu dojde v konstantním výrazu k přetečení, dojde k chybě v době kompilace. V opačném případě je vyvolán při provedení operace za běhu OverflowException .
  • V nezaškrtnutém kontextu se výsledek zkrátí tak, že zahodí všechny bity s vysokým pořadím, které se nevejdou do cílového typu.

Spolu se zaškrtnutými a nezaškrtnutými příkazy můžete pomocí checked operátorů unchecked řídit kontext kontroly přetečení, ve kterém se výraz vyhodnotí:

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

Ve výchozím nastavení se aritmetické operace vyskytují v nezaškrtnutém kontextu.

Aritmetické přetečení s plovoucí desetinou čárkou

Aritmetické operace s float typy a double nikdy nevyvolají výjimku. Výsledkem aritmetických operací s těmito typy může být jedna ze speciálních hodnot, které představují nekonečno a nikoli číslo:

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

Pro operandy decimal typu, aritmetické přetečení vždy vyvolá .OverflowException Dělení nulou vždy vyvolá chybu DivideByZeroException.

Chyby zaokrouhlení

Vzhledem k obecným omezením reprezentace skutečných čísel a aritmetických hodnot s plovoucí desetinou čárkou může ve výpočtech s typy s plovoucí desetinou čárkou dojít k chybám zaokrouhlení. To znamená, že vytvořený výsledek výrazu se může lišit od očekávaného matematického výsledku. Následující příklad ukazuje několik takových případů:

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

Další informace naleznete v poznámkách na stránkách odkazu System.Double, System.Single nebo System.Decimal .

Přetížení operátoru

Uživatelem definovaný typ může přetížit unární (++, --, +a -) a binární operátory (*, /, %, +, a ) aritmetické -operátory. Pokud je binární operátor přetížen, odpovídající operátor složeného přiřazení je také implicitně přetížen. Počínaje jazykem C# 14 může uživatelem definovaný typ explicitně přetížit operátory složeného přiřazení (op=), aby poskytoval efektivnější implementaci. Typ obvykle přetěžuje tyto operátory, protože hodnotu lze aktualizovat místo přidělení nové instance k uložení výsledku operace. Pokud typ neposkytuje explicitní přetížení, kompilátor vygeneruje implicitní přetížení.

Uživatelem definované kontrolované operátory

Počínaje jazykem C# 11 můžete při přetížení aritmetického operátoru definovat ověřenou checked verzi tohoto operátoru pomocí klíčového slova. Následující příklad ukazuje, jak to udělat:

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

Při definování kontrolovaného operátoru musíte také definovat odpovídající operátor bez modifikátoru checked . Kontrolovaný operátor se volá v kontrolovaném kontextu. Operátor bez modifikátoru checked se volá v nezaškrtnutém kontextu. Pokud operátor zadáte pouze bez modifikátoru checked , zavolá se v kontextu checked i unchecked v kontextu.

Při definování obou verzí operátoru se očekává, že se jejich chování liší pouze v případě, že výsledek operace je příliš velký, aby představoval v typu výsledku následujícím způsobem:

  • Kontrolovaná operátor vyvolá výjimku OverflowException.
  • Operátor bez modifikátoru checked vrátí instanci představující zkrácený výsledek.

Informace o rozdílu v chování předdefinovaných aritmetických operátorů najdete v části Aritmetické přetečení a dělení nulou .

Modifikátor můžete použít checked pouze v případě, že přetížíte některý z následujících operátorů:

  • Unární ++, --a - operátory
  • Binární *, /, +, a - operátory
  • Složené přiřazení *=, /=, += a -= operátory (C# 14 a novější)
  • Explicitní operátory převodu

Poznámka:

Kontext kontroly přetečení v těle kontrolního operátoru není ovlivněn přítomností modifikátoru checked . Výchozí kontext je definován hodnotou CheckForOverflowUnderflow compiler option. checked můžete unchecked explicitně určit kontext kontroly přetečení, jak ukazuje příklad na začátku této části.

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také