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 jsou podporovány všemi celočíselnými a číselnými typy s plovoucí desetinou čárkou .

V případě integrálních typů jsou tyto operátory (kromě ++ operátorů -- ) definovány pro operátory int, uint, longa ulong typy. Pokud jsou operandy jiného celočíselného typu (sbyte, byte, short, ushortnebo char), jejich hodnoty se převedou na int typ, což je také typ výsledku operace. 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 ani floatdouble, 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 n|x| - n * |y| 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á té, která se používá 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 ekvivalentem

x = x op y

s tím rozdílem, že x se vyhodnotí pouze 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 op operace implicitně konvertibilní na typ Tx. V takovém případě je-li op předdefinovaný operátor a výsledek operace je explicitně konvertibilní na typ xT , 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. Uživatelem definovaný typ nemůže explicitně přetížit operátor složeného přiřazení.

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 verzi tohoto operátoru pomocí checked 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ů:

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 Pomocí příkazů 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é