The five operators
C# can calculate with numbers directly, or with variables that hold numbers. The arithmetic operators are:
| Operator | Name | Example | Result |
|---|---|---|---|
+ | Addition | 2 + 6 | 8 |
- | Subtraction | 10 - 7 | 3 |
* | Multiplication | 3 * 3 | 9 |
/ | Division | 6 / 2 | 3 |
% | Remainder (modulus) | 8 % 3 | 2 |
When a variable appears in an expression, C# uses its current value:
int num = 6;
Console.WriteLine(num + 5); // 11
Console.WriteLine(10 - num); // 4
Console.WriteLine(3 * num); // 18
Console.WriteLine(num / 2); // 3
An expression only calculates a value, and that value is used wherever the expression appears. It does not change the variables in it. After the lines above, num is still 6. To change a variable you must assign the result with =, for example num = num + 5;.
Integer division
This is the detail that surprises beginners. When both operands are integers, / performs integer division and throws away the fractional part. It truncates toward zero and does not round:
Console.WriteLine(20 / 3); // 6
Console.WriteLine(3 / 2); // 1
To get a fractional result, at least one operand must be a double. A double literal has a decimal point:
Console.WriteLine(7 / 2.0); // 3.5
Casting is the other route, but mind where the cast applies. A cast binds tighter than /, so (double) 7 / 3 converts only the 7 and gives 2.3333333333333335. Casting either operand is enough: 3 / (double) 2 gives 1.5. And (double) (7 / 3) is wrong in another way, since the integer division happens first, leaving 2. Order matters in longer expressions too: 7 / 2 * 2.0 is 6, because 7 / 2 runs first as integer division, while 7 / 2.0 * 2 is 7.
The rule is that C# converts the int to a double whenever the two operands differ, and the result is a double. That result can't be stored in an int variable without a cast, so int half = 7 / 2.0; fails to compile. Use double half = 7 / 2.0; instead.
The remainder operator
% gives what is left over after integer division. 8 % 3 is 2, because 3 fits into 8 twice with 2 left. It is handy for checking whether a number is even (n % 2 == 0) or for wrapping around a range. With negative numbers, the result takes the sign of the left operand: -7 % 3 is -1.
Order of evaluation
C# follows the usual rules: multiplication, division and remainder happen before addition and subtraction, and parentheses override both.
Console.WriteLine(2 + 3 * 4); // 14
Console.WriteLine((2 + 3) * 4); // 20
Shortcuts for updating a variable
Assigning the result of an operation back to the same variable is so common that C# has shorthand forms:
int score = 10;
score += 5; // same as score = score + 5; now 15
score *= 2; // same as score = score * 2; now 30
score++; // adds one; now 31
These are assignments, so they do change the variable.
Things that go wrong
- Overflow. An
inthas a fixed range, up to 2,147,483,647. In ordinary code, going past it does not fail: the value wraps around, so ifbigholdsint.MaxValue,big + 1is-2147483648. (Written with constants,int.MaxValue + 1is caught by the compiler instead.) - Dividing integers by zero.
a / 0with anintvariable throws aDivideByZeroExceptionat run time. Withdouble, the result isInfinityinstead of an exception. - Floating-point noise.
0.1 + 0.2prints0.30000000000000004becausedoublestores binary approximations. - Mixing text and numbers.
"Total: " + 1 + 2joins text and givesTotal: 12; put the sum in parentheses.
The exercise, step by step
The variable price holds the cost of one product, 83. Andy buys 4 products at that price and one bag for 15, and the program must print the total.
- Multiply the quantity by the price.
4 * priceis the cost of the products. - Add the bag. Adding
15gives4 * price + 15. - Put it inside
Console.WriteLine. Parentheses aren't needed, since multiplication runs before addition. Writing(4 * price) + 15would be harmless but is redundant.
int price = 83;
Console.WriteLine(4 * price + 15);
The program prints 347: 4 times 83 is 332, and 332 plus 15 is 347. If the addition ran first, you would get 4 * (83 + 15), which is 392, so precedence changes the answer.
Key takeaways
+,-,*,/and%work on numbers and variables holding numbers.- Integer division discards the fraction; make one operand a
doubleto keep it. - Multiplication, division and remainder come before addition and subtraction.
- Expressions don't change variables; assignment does.
- Mixing an
intand adoublegives adouble, and storing that in anintneeds an explicit cast.