Menu

C# Operators: Arithmetic, Modulo, Logical, Bitwise and Precedence

The C# operators with their exact behavior: integer division, the modulo operator with negative numbers, increment and compound assignment, comparison, short-circuit logic, bitwise operators, the null operators, and a precedence table.

This page includes runnable editors - edit, run, and see output instantly.

An operator takes one, two or three operands and produces a value: a + b, !done, x ?? fallback. C#'s operators are close to those of C, Java and JavaScript, but a few behave in ways that surprise newcomers, above all integer division and the sign of %.

Arithmetic operators

+, -, *, / and % work on every numeric type. The type of the result follows the operands: two int values produce an int, an int and a double produce a double.

Output:

22
12
85
3
2
3.4
3.4
3
3.4

Integer division truncates toward zero. 17 / 5 is 3 and -17 / 5 is -3. It causes a very common bug: int percent = done / total * 100; is 0 whenever done < total, because done / total is already 0. Multiply first (done * 100 / total) or divide as double.

Dividing an integer or decimal by zero throws DivideByZeroException. Dividing a double by zero does not throw; it produces infinity, or NaN for 0.0 / 0.0:

Output:

True
True
False
DivideByZeroException

The modulo operator and negative numbers

% returns the remainder of the division, and its result takes the sign of the left operand. This differs from Python and from the mathematical "mod", which are always non-negative for a positive divisor:

Output:

1
-1
1
2
even
62 min 5 s
Thu
1.5

Use the Mod helper whenever the left side can be negative and the result is an index: days[(today + offset) % 7] would throw an IndexOutOfRangeException for a negative sum. Testing for odd numbers has the same trap: n % 2 == 1 is false for negative odd numbers; test n % 2 != 0.

Assignment, compound assignment and increment

= assigns. The compound forms +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= combine an operation with assignment. ++ and -- add or subtract 1, and come in prefix and postfix forms that differ in the value they return:

Output:

14
start, step
a=5 b=7 i=7
4

The byte case shows a quirk: level = level + 10; does not compile, because byte + int is an int, but level += 10; does, because compound assignment includes an implicit cast back to the variable's type. That cast wraps on overflow (250 + 10 becomes 4).

Comparison and logical operators

Comparison operators (==, !=, <, >, <=, >=) return a bool. For strings, == compares the text, not the references. The logical operators are ! (not), && (and), || (or) and ^ (exclusive or).

Output:

True
no active user
with ||:
  evaluated A
with |:
  evaluated A
  evaluated B
True

&& and || short-circuit: the right operand runs only when it can change the result. That is what makes user != null && user.IsActive safe. The single & and | on booleans always evaluate both sides, which is rarely what you want in a condition.

Bitwise and shift operators

On integer types, &, |, ^ and ~ work on individual bits, and << and >> shift them. They are used for flags, masks, hashing and low-level protocols:

Output:

3
True
False
101
1024
125
5
-1

For named sets of flags, an enum with the [Flags] attribute is clearer than integer constants, and HasFlag reads better than a mask. C# 11 added >>>, an unsigned right shift that fills with zeros even for negative numbers.

Null operators

Three operators exist for working with values that may be null:

Output:

Guest

0
5

a ?? b returns a unless it is null, then b. a?.Member returns null instead of throwing when a is null. C# 8 added a ??= b, which assigns b to a only when a is null. These are covered in depth in nullable types.

Operator precedence

When an expression mixes operators, higher rows bind tighter. Operators in the same row group left to right, except assignment, ?? and ?:, which group right to left. (Operands themselves are always evaluated left to right.)

CategoryOperators
Primaryx.y, x?.y, f(x), a[i], x++, x--, new, typeof, nameof
Unary+x, -x, !x, ~x, ++x, --x, (T)x, await
Multiplicative*, /, %
Additive+, -
Shift<<, >>, >>>
Relational and type testing<, >, <=, >=, is, as
Equality==, !=
Bitwise AND&
Bitwise XOR^
Bitwise OR|
Conditional AND&&
Conditional OR||
Null coalescing??
Conditionalc ? a : b
Assignment and lambda=, +=, -=, ??=, =>, and the other compound forms

Two consequences worth knowing: a + b * c multiplies first, and x & mask == 0 compares first (== binds tighter than &), so it means x & (mask == 0) and does not compile for integers. Write (x & mask) == 0. Parentheses cost nothing and make intent obvious.

Operator overloading

Your own types can define what operators mean. This is how decimal, DateTime and TimeSpan support + and <:

Output:

33.49
True

Operators must be public static, and some come in required pairs: defining < requires >, and == requires !=. With == defined, the compiler also warns until you override Equals and GetHashCode to match. Overload operators only where the meaning is obvious, as with numbers, vectors and money.

Frequently Asked Questions

What does % do in C#?

% is the remainder operator: 17 % 5 is 2. The result has the sign of the left operand, so -7 % 3 is -1, not 2 as in Python. For a result that is always non-negative, as you need when wrapping an index, write ((a % n) + n) % n. It also works on double and decimal: 7.5 % 2 is 1.5.

Why does 7 / 2 equal 3 in C#?

When both operands are integers, / performs integer division and discards the fractional part, truncating toward zero. Make one operand a floating-point or decimal value to get a fractional result: 7 / 2.0 is 3.5, (double)a / b converts before dividing, and 7m / 2 is 3.5 as a decimal.

What is the difference between && and & in C#?

&& is the conditional AND: if the left side is false, the right side is not evaluated. & on booleans always evaluates both sides, and on integers it is the bitwise AND. Use && and || for conditions, especially guards like user != null && user.IsActive, which would throw a NullReferenceException with &.

What is the difference between i++ and ++i in C#?

Both add 1 to i. The expression i++ evaluates to the old value, ++i to the new value. On a line by itself (i++;) there is no difference. It matters only when the result is used, as in int a = i++;, which is why many style guides keep increments on their own line.

What is the operator precedence in C#?

From highest to lowest: primary (x.y, f(x), a[i], x++), unary (!, -, ++x, casts), multiplicative (* / %), additive (+ -), shifts, relational (< > <= >= is as), equality (== !=), &, ^, |, &&, ||, ??, the conditional ?:, and finally assignment. When in doubt, add parentheses.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED