Arithmetic operators (C# Reference)

The following operators perform arithmetic operations with numeric types:

Those operators support all integral and floating-point numeric types.

Increment operator ++

The unary increment operator ++ increments its operand by 1. The operand must be a variable, a property access, or an indexer access.

The increment operator is supported in two forms: the postfix increment operator, x++, and the prefix increment operator, ++x.

Postfix increment operator

The result of x++ is the value of x before the operation, as the following example shows:

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

Prefix increment operator

The result of ++x is the value of x after the operation, as the following example shows:

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

Decrement operator --

The unary decrement operator -- decrements its operand by 1. The operand must be a variable, a property access, or an indexer access.

The decrement operator is supported in two forms: the postfix decrement operator, x--, and the prefix decrement operator, --x.

Postfix decrement operator

The result of x-- is the value of x before the operation, as the following example shows:

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

Prefix decrement operator

The result of --x is the value of x after the operation, as the following example shows:

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

Unary plus and minus operators

The unary + operator returns the value of its operand. The unary - operator computes the numeric negation of its operand.

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

The unary - operator doesn't support the ulong type.

Multiplication operator *

The multiplication operator * computes the product of its operands:

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

The unary * operator is the pointer indirection operator.

Division operator /

The division operator / divides its first operand by its second operand.

Integer division

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: 2
Console.WriteLine(-13 / 5);   // output: -2
Console.WriteLine(13 / -5);   // output: -2
Console.WriteLine(-13 / -5);  // output: 2

To obtain the quotient of the two operands as a floating-point number, use the float, double, or decimal type:

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

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

Floating-point division

For the float, double, and decimal types, the result of the / operator is the quotient of the two operands:

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

If one of the operands is decimal, another operand can be neither float nor double, because neither float nor double is implicitly convertible to decimal. You must explicitly convert the float or double operand to the decimal type. For more information about implicit conversions between numeric types, see Implicit numeric conversions table.

Remainder operator %

The remainder operator % computes the remainder after dividing its first operand by its second operand.

Integer remainder

For the operands of integer types, the result of a % b is the value produced by a - (a / b) * b. The sign of the non-zero remainder is the same as that of the first operand, as the following example shows:

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

Use the Math.DivRem method to compute both integer division and remainder results.

Floating-point remainder

For the float and double operands, the result of x % y for the finite x and y is the value z such that

  • The sign of z, if non-zero, is the same as the sign of x.
  • The absolute value of z is the value produced by |x| - n * |y| where n is the largest possible integer that is less than or equal to |x| / |y| and |x| and |y| are the absolute values of x and y, respectively.

Note

This method of computing the remainder is analogous to that used for integer operands, but differs from the IEEE 754. If you need the remainder operation that complies with the IEEE 754, use the Math.IEEERemainder method.

For information about the behavior of the % operator with non-finite operands, see the Remainder operator section of the C# language specification.

For the decimal operands, the remainder operator % is equivalent to the remainder operator of the System.Decimal type.

The following example demonstrates the behavior of the remainder operator with floating-point operands:

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

Addition operator +

The addition operator + computes the sum of its operands:

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

You also can use the + operator for string concatenation and delegate combination. For more information, see the + operator article.

Subtraction operator -

The subtraction operator - subtracts its second operand from its first operand:

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

You also can use the - operator for delegate removal. For more information, see the - operator article.

Operator precedence and associativity

The following list orders arithmetic operators starting from the highest precedence to the lowest:

  • Postfix increment x++ and decrement x-- operators
  • Prefix increment ++x and decrement --x and unary + and - operators
  • Multiplicative *, /, and % operators
  • Additive + and - operators

Binary 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: 6
Console.WriteLine((2 + 2) * 2); // output: 8

Console.WriteLine(9 / 5 / 2);   // output: 0
Console.WriteLine(9 / (5 / 2)); // output: 4

For the complete list of C# operators ordered by precedence level, see C# operators.

Compound assignment

For a binary operator op, a compound assignment expression of the form

x op= y

is equivalent to

x = x op y

except that x 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: 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

Because of numeric promotions, the result of the op operation might be not implicitly convertible to the type T of x. In such a case, if op is a predefined operator and the result of the operation is explicitly convertible to the type T of x, a compound assignment expression of the form x op= y is equivalent to x = (T)(x op y), except that x 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.Int32
Console.WriteLine(c);  // output: 300

a += b;
Console.WriteLine(a);  // output: 44

You also use the += and -= operators to subscribe to and unsubscribe from events. For more information, see How to: subscribe to and unsubscribe from events.

Arithmetic overflow and division by zero

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 arithmetic overflow

Integer division by zero always throws a DivideByZeroException.

In case of integer arithmetic overflow, an overflow checking context, which can be checked or unchecked, controls the resulting behavior:

  • In a checked context, if overflow happens in a constant expression, a compile-time error occurs. Otherwise, when the operation is performed at run time, an OverflowException is thrown.
  • In an unchecked context, the result is truncated by discarding any high-order bits that don't fit in the destination type.

Along with the checked and unchecked statements, you can use the checked and unchecked 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: -2147483646
try
{
    int d = checked(a + b);
}
catch(OverflowException)
{
    Console.WriteLine($"Overflow occured when adding {a} to {b}.");
}

By default, arithmetic operations occur in an unchecked context.

Floating-point arithmetic overflow

Arithmetic operations with the float and double 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: 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

For the operands of the decimal type, arithmetic overflow always throws an OverflowException and division by zero always throws a DivideByZeroException.

Round-off errors

Because of general limitations of the floating-point representation of real numbers and floating-point arithmetic, the 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.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

For more information, see remarks at System.Double, System.Single, or System.Decimal reference pages.

Operator overloadability

A user-defined type can overload the unary (++, --, +, and -) and binary (*, /, %, +, and -) arithmetic operators. When a binary operator is overloaded, the corresponding compound assignment operator is also implicitly overloaded. A user-defined type cannot explicitly overload a compound assignment operator.

C# language specification

For more information, see the following sections of the C# language specification:

See also