C in 100 Seconds: Arithmetic Operators | Episode 4
Video: C in 100 Seconds: Arithmetic Operators | Episode 4 by Taught by Celeste AI - AI Coding Coach
C Arithmetic Operators
+ - * /and%(modulo). The classic gotcha:17 / 5is3, not3.4. Integer division truncates. Use a float operand to get the decimal back.
C's arithmetic looks like math, mostly. Integer division is the one big surprise — and one of the most common bugs in early C code.
The five operators
#include <stdio.h>
int main() {
int a = 17, b = 5;
printf("%d + %d = %d\n", a, b, a + b); // 22
printf("%d - %d = %d\n", a, b, a - b); // 12
printf("%d * %d = %d\n", a, b, a * b); // 85
printf("%d / %d = %d\n", a, b, a / b); // 3 (!)
printf("%d %% %d = %d\n", a, b, a % b); // 2
return 0;
}
+, -, *, /, %. Standard for any C-family language. %% in the format string prints a literal % (because a single % would start a format specifier).
Integer division truncates
printf("17 / 5 = %d\n", 17 / 5); // 3
printf("17.0 / 5 = %.1f\n", 17.0 / 5); // 3.4
When both operands are integers, / truncates toward zero. 17 / 5 is 3 (not 3.4, not 4).
To get the decimal answer, at least one operand must be a float or double:
17.0 / 5→3.417 / 5.0→3.4(double)17 / 5→3.4(explicit cast)
If you accidentally use two ints, your decimal result becomes integer:
double avg = 17 / 5; // 3.0 (because 17/5 is 3, then promoted to double)
To fix:
double avg = 17.0 / 5; // 3.4
This is one of the top three bugs in beginner C code. Always check types before division.
Modulo: the remainder
printf("17 %% 5 = %d\n", 17 % 5); // 2
a % b is the remainder of a / b. For 17/5: quotient is 3, remainder is 2 (because 5×3 + 2 = 17).
Useful for:
- Even/odd:
n % 2is 0 if even, 1 if odd. - Loop step: "every Nth iteration":
if (i % 10 == 0). - Wrapping:
index % sizealways falls in [0, size). - Digit extraction:
n % 10is the last digit ofn.
% only works on integers. 17.0 % 5 doesn't compile — for floats, use fmod from math.h:
#include <math.h>
double r = fmod(17.5, 5.0); // 2.5
Negative modulo
printf("%d\n", -17 % 5); // -2 (in C99+)
printf("%d\n", 17 % -5); // 2
In C99 and later, % matches the dividend's sign. -17 % 5 is -2, not 3. Different from Python, which returns 3.
For "true" modulo (always non-negative):
int true_mod(int a, int b) {
int r = a % b;
return (r < 0) ? r + b : r;
}
Operator precedence
int x = 2 + 3 * 4; // 14, not 20
int y = (2 + 3) * 4; // 20
Standard math precedence:
()— explicit- unary
-,+,!,~ *,/,%+,-
When in doubt, parenthesize. Code clarity beats character count.
Increment and decrement
int i = 5;
i++; // i = 6
i--; // i = 5
++i; // i = 6 (prefix)
int x = 5;
int y = x++; // y = 5, then x = 6 (post-increment)
int z = ++x; // x = 7, then z = 7 (pre-increment)
i++ returns the old value, then increments. ++i increments first, then returns the new value. Inside expressions this matters; as a standalone statement it doesn't.
Avoid using ++/-- inside complex expressions — readability suffers and undefined behavior lurks (a[i++] = i; has undefined evaluation order).
Compound assignment
int x = 10;
x += 3; // x = x + 3 = 13
x -= 2; // x = 11
x *= 5; // x = 55
x /= 4; // x = 13 (integer division!)
x %= 5; // x = 3
Shorthand for x = x op value. Same precedence rules.
Mixing types
int i = 5;
double d = 2.5;
double r = i + d; // 7.5 — i promoted to double
int n = i + d; // 7 — entire expression cast to int (truncate!)
C automatically promotes the smaller type to the larger one (int → double). The result type is the larger.
When assigning to a smaller type, the value is converted (truncated for float-to-int). The compiler may warn (-Wconversion).
Common mistakes
Integer division by accident. int avg = total / count; when total/count is meant to be a decimal. Use (double)total / count.
Modulo with float. 17.5 % 5 doesn't compile. Use fmod(17.5, 5.0).
Off-by-one with %. i % size for index in array of size size is 0 to size-1 — correct for arrays. But i % size for "1-based" indexing breaks at size (gives 0, not size).
Operator precedence guesses. 1 << 2 + 3 is 1 << (2 + 3) = 32, not (1 << 2) + 3 = 7. Parenthesize bit-shifts.
Division by zero. 5 / 0 is undefined behavior. Compile-time constant: error. Runtime: usually a SIGFPE crash (Linux/macOS) or silent garbage. Always check.
Overflow. 2000000000 * 2 (fits in int?) overflows silently. Result is undefined. Use long or int64_t for large products.
What's next
Episode 5: if / else. Conditional branching, ternary operator, and a 14-line grade calculator.
Recap
+ - * / plus % (integer remainder). Integer division truncates: 17/5 = 3. Use a float operand for decimal: 17.0 / 5 = 3.4. % only works on ints; use fmod for floats. % matches dividend's sign in C99+. Compound assignment: +=, -=, etc. Increment: i++ (post) returns old then increments; ++i (pre) increments then returns new. Watch for division by zero (undefined) and integer overflow (undefined).
Next episode: if/else.