This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
The following operators perform arithmetic operations with operands of numeric types:
++
(increment),--
(decrement),+
(plus), and-
(minus) operators*
(multiplication),/
(division),%
(remainder),+
(addition), and-
(subtraction) operatorsAllintegral andfloating-point numeric types support these operators.
Theint
,uint
,long
, andulong
types define all these operators. The other integral types (sbyte
,byte
,short
,ushort
, andchar
) define only the++
and--
operators. For other operators, when operands are of the integral typessbyte
,byte
,short
,ushort
, orchar
, their values are converted to theint
type and the result type isint
. When operands are of different integral or floating-point types, their values are converted to the closest containing type, if such a type exists. For more information, see theNumeric promotions section of theC# language specification. The++
and--
operators are defined for all integral and floating-point numeric types and thechar type. The result type of acompound assignment expression is the type of the left-hand operand.
The unary increment operator++
increments its operand by 1. The operand must be a variable, aproperty access, or anindexer access.
The increment operator is supported in two forms: the postfix increment operator,x++
, and the prefix increment operator,++x
.
The result ofx++
is the value ofx
before the operation, as the following example shows:
int i = 3;Console.WriteLine(i); // output: 3Console.WriteLine(i++); // output: 3Console.WriteLine(i); // output: 4
The result of++x
is the value ofx
after the operation, as the following example shows:
double a = 1.5;Console.WriteLine(a); // output: 1.5Console.WriteLine(++a); // output: 2.5Console.WriteLine(a); // output: 2.5
The unary decrement operator--
decrements its operand by 1. The operand must be a variable, aproperty access, or anindexer access.
The decrement operator is supported in two forms: the postfix decrement operator,x--
, and the prefix decrement operator,--x
.
The result ofx--
is the value ofx
before the operation, as the following example shows:
int i = 3;Console.WriteLine(i); // output: 3Console.WriteLine(i--); // output: 3Console.WriteLine(i); // output: 2
The result of--x
is the value ofx
after the operation, as the following example shows:
double a = 1.5;Console.WriteLine(a); // output: 1.5Console.WriteLine(--a); // output: 0.5Console.WriteLine(a); // output: 0.5
The unary+
operator returns the value of its operand. The unary-
operator computes the numeric negation of its operand.
Console.WriteLine(+4); // output: 4Console.WriteLine(-4); // output: -4Console.WriteLine(-(-4)); // output: 4uint a = 5;var b = -a;Console.WriteLine(b); // output: -5Console.WriteLine(b.GetType()); // output: System.Int64Console.WriteLine(-double.NaN); // output: NaN
Theulong type doesn't support the unary-
operator.
The multiplication operator*
computes the product of its operands:
Console.WriteLine(5 * 2); // output: 10Console.WriteLine(0.5 * 2.5); // output: 1.25Console.WriteLine(0.1m * 23.4m); // output: 2.34
The unary*
operator is thepointer indirection operator.
The division operator/
divides its left-hand operand by its right-hand operand.
For the operands of integer types, the result of the/
operator is of an integer type and equals the quotient of the two operands rounded towards zero:
Console.WriteLine(13 / 5); // output: 2Console.WriteLine(-13 / 5); // output: -2Console.WriteLine(13 / -5); // output: -2Console.WriteLine(-13 / -5); // output: 2
To obtain the quotient of the two operands as a floating-point number, use thefloat
,double
, ordecimal
type:
Console.WriteLine(13 / 5.0); // output: 2.6int a = 13;int b = 5;Console.WriteLine((double)a / b); // output: 2.6
For thefloat
,double
, anddecimal
types, the result of the/
operator is the quotient of the two operands:
Console.WriteLine(16.8f / 4.1f); // output: 4.097561Console.WriteLine(16.8d / 4.1d); // output: 4.09756097560976Console.WriteLine(16.8m / 4.1m); // output: 4.0975609756097560975609756098
If one of the operands isdecimal
, another operand can't befloat
nordouble
, because neitherfloat
nordouble
is implicitly convertible todecimal
. You must explicitly convert thefloat
ordouble
operand to thedecimal
type. For more information about conversions between numeric types, seeBuilt-in numeric conversions.
The remainder operator%
computes the remainder after dividing its left-hand operand by its right-hand operand.
For the operands of integer types, the result ofa % b
is the value produced bya - (a / b) * b
. The sign of the non-zero remainder is the same as the sign of the left-hand operand, as the following example shows:
Console.WriteLine(5 % 4); // output: 1Console.WriteLine(5 % -4); // output: 1Console.WriteLine(-5 % 4); // output: -1Console.WriteLine(-5 % -4); // output: -1
Use theMath.DivRem method to compute both integer division and remainder results.
For thefloat
anddouble
operands, the result ofx % y
for the finitex
andy
is the valuez
such that
z
, if non-zero, is the same as the sign ofx
.z
is the value produced by|x| - n * |y|
wheren
is the largest possible integer that is less than or equal to|x| / |y|
and|x|
and|y|
are the absolute values ofx
andy
, respectively.Note
This method of computing the remainder is analogous to the method used for integer operands, but different from the IEEE 754 specification. If you need the remainder operation that complies with the IEEE 754 specification, use theMath.IEEERemainder method.
For information about the behavior of the%
operator with non-finite operands, see theRemainder operator section of theC# language specification.
For thedecimal
operands, the remainder operator%
is equivalent to theremainder operator of theSystem.Decimal type.
The following example demonstrates the behavior of the remainder operator with floating-point operands:
Console.WriteLine(-5.2f % 2.0f); // output: -1.2Console.WriteLine(5.9 % 3.1); // output: 2.8Console.WriteLine(5.9m % 3.1m); // output: 2.8
The addition operator+
computes the sum of its operands:
Console.WriteLine(5 + 4); // output: 9Console.WriteLine(5 + 4.3); // output: 9.3Console.WriteLine(5.1m + 4.2m); // output: 9.3
You can also use the+
operator for string concatenation and delegate combination. For more information, see the+
and+=
operators article.
The subtraction operator-
subtracts its right-hand operand from its left-hand operand:
Console.WriteLine(47 - 3); // output: 44Console.WriteLine(5 - 4.3); // output: 0.7Console.WriteLine(7.5m - 2.3m); // output: 5.2
You can also use the-
operator for delegate removal. For more information, see the-
and-=
operators article.
For a binary operatorop
, a compound assignment expression of the form
x op= y
Is equivalent to
x = x op y
Except thatx
is only evaluated once.
The following example demonstrates the usage of compound assignment with arithmetic operators:
int a = 5;a += 9;Console.WriteLine(a); // output: 14a -= 4;Console.WriteLine(a); // output: 10a *= 2;Console.WriteLine(a); // output: 20a /= 4;Console.WriteLine(a); // output: 5a %= 3;Console.WriteLine(a); // output: 2
Because ofnumeric promotions, the result of theop
operation might be not implicitly convertible to the typeT
ofx
. In such a case, ifop
is a predefined operator and the result of the operation is explicitly convertible to the typeT
ofx
, a compound assignment expression of the formx op= y
is equivalent tox = (T)(x op y)
, except thatx
is only evaluated once. The following example demonstrates that behavior:
byte a = 200;byte b = 100;var c = a + b;Console.WriteLine(c.GetType()); // output: System.Int32Console.WriteLine(c); // output: 300a += b;Console.WriteLine(a); // output: 44
In the preceding example, value44
is the result of converting value300
to thebyte
type.
Note
In thechecked overflow-checking context, the preceding example throws anOverflowException. For more information, see theInteger arithmetic overflow section.
You also use the+=
and-=
operators to subscribe to and unsubscribe from anevent, respectively. For more information, seeHow to subscribe to and unsubscribe from events.
The following list orders arithmetic operators starting from the highest precedence to the lowest:
x++
and decrementx--
operators++x
and decrement--x
and unary+
and-
operators*
,/
, and%
operators+
and-
operatorsBinary arithmetic operators are left-associative. That is, operators with the same precedence level are evaluated from left to right.
Use parentheses,()
, to change the order of evaluation imposed by operator precedence and associativity.
Console.WriteLine(2 + 2 * 2); // output: 6Console.WriteLine((2 + 2) * 2); // output: 8Console.WriteLine(9 / 5 / 2); // output: 0Console.WriteLine(9 / (5 / 2)); // output: 4
For the complete list of C# operators ordered by precedence level, see theOperator precedence section of theC# operators article.
When the result of an arithmetic operation is outside the range of possible finite values of the involved numeric type, the behavior of an arithmetic operator depends on the type of its operands.
Integer division by zero always throws aDivideByZeroException.
If integer arithmetic overflow occurs, the overflow-checking context, which can bechecked or unchecked, controls the resulting behavior:
Along with thechecked and unchecked statements, you can use thechecked
andunchecked
operators to control the overflow-checking context, in which an expression is evaluated:
int a = int.MaxValue;int b = 3;Console.WriteLine(unchecked(a + b)); // output: -2147483646try{ int d = checked(a + b);}catch(OverflowException){ Console.WriteLine($"Overflow occurred when adding {a} to {b}.");}
By default, arithmetic operations occur in anunchecked context.
Arithmetic operations with thefloat
anddouble
types never throw an exception. The result of arithmetic operations with those types can be one of special values that represent infinity and not-a-number:
double a = 1.0 / 0.0;Console.WriteLine(a); // output: InfinityConsole.WriteLine(double.IsInfinity(a)); // output: TrueConsole.WriteLine(double.MaxValue + double.MaxValue); // output: Infinitydouble b = 0.0 / 0.0;Console.WriteLine(b); // output: NaNConsole.WriteLine(double.IsNaN(b)); // output: True
For the operands of thedecimal
type, arithmetic overflow always throws anOverflowException. Division by zero always throws aDivideByZeroException.
Because of general limitations of the floating-point representation of real numbers and floating-point arithmetic, round-off errors might occur in calculations with floating-point types. That is, the produced result of an expression might differ from the expected mathematical result. The following example demonstrates several such cases:
Console.WriteLine(.41f % .2f); // output: 0.00999999double a = 0.1;double b = 3 * a;Console.WriteLine(b == 0.3); // output: FalseConsole.WriteLine(b - 0.3); // output: 5.55111512312578E-17decimal c = 1 / 3.0m;decimal d = 3 * c;Console.WriteLine(d == 1.0m); // output: FalseConsole.WriteLine(d); // output: 0.9999999999999999999999999999
For more information, see remarks at theSystem.Double,System.Single, orSystem.Decimal reference pages.
A user-defined type canoverload the unary (++
,--
,+
, and-
) and binary (*
,/
,%
,+
, and-
) arithmetic operators. When a binary operator is overloaded, the corresponding compound assignment operator is also implicitly overloaded. Beginning with C# 14, a user-defined type can explicitly overload the compound assignment operators (op=
) to provide a more efficient implementation. Typically, a type overloads these operators because the value can be updated in place, rather than allocating a new instance to store the result of the operation. If a type doesn't provide an explicit overload, the compiler generates the implicit overload.
Beginning with C# 11, when you overload an arithmetic operator, you can use thechecked
keyword to define thechecked version of that operator. The following example shows how to do that:
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); }}
When you define a checked operator, you must also define the corresponding operator without thechecked
modifier. The checked operator is called in achecked context; the operator without thechecked
modifier is called in anunchecked context. If you only provide the operator without thechecked
modifier, it's called in both achecked
andunchecked
context.
When you define both versions of an operator, it's expected that their behavior differs only when the result of an operation is too large to represent in the result type as follows:
checked
modifier returns an instance representing atruncated result.For information about the difference in behavior of the built-in arithmetic operators, see theArithmetic overflow and division by zero section.
You can use thechecked
modifier only when you overload any of the following operators:
++
,--
, and-
operators*
,/
,+
, and-
operators*=
,/=
,+=
, and-=
operators (C# 14 and later)Note
The overflow-checking context within the body of a checked operator isn't affected by the presence of thechecked
modifier. The default context is defined by the value of theCheckForOverflowUnderflow compiler option. Use thechecked
andunchecked
statements to explicitly specify the overflow-checking context, as the example at the beginning of this section demonstrates.
For more information, see the following sections of theC# language specification:
Was this page helpful?
Was this page helpful?