Quotient and remainder
Dividing 20 by 3 can be read two ways. As a real number it is 6.666..., but as a question of whole groups it is "6 times, with 2 left over". The 6 is the quotient, the number of times the divisor fits completely. The 2 is the remainder, what doesn't fit.
10 / 2 = quotient 5, remainder 0
15 / 4 = quotient 3, remainder 3
20 / 3 = quotient 6, remainder 2
Integer division with /
When both operands of / are integers, Rust returns the quotient and discards the remainder. There is no special operator for it: the type of the operands decides.
println!("{}", 10 / 2); // 5
println!("{}", 15 / 4); // 3
println!("{}", 20 / 3); // 6
let a = 3;
let b = 7;
println!("{}", 20 / a); // 6
println!("{}", b / a); // 2
If either side is a float, the division is a real division instead: 15.0 / 4.0 is 3.75. Rust won't mix the two kinds in one expression, so you can't accidentally get one when you meant the other.
Truncation versus floor
The lesson is named floor division, which rounds down toward negative infinity. Rust's integer division actually truncates toward zero. For positive numbers the two are identical, so 70 / 15 is 4 either way. They differ for negative results: -7 / 2 is -3 in Rust, whereas true floor division would give -4. If you need the floor for negative numbers, use (-7_i32).div_euclid(2), which is -4.
The remainder operator %
The % operator returns the remainder:
println!("{}", 10 % 2); // 0
println!("{}", 15 % 4); // 3
println!("{}", 20 % 3); // 2
let a = 2;
let b = 4;
println!("{}", b % a); // 0
println!("{}", 11 % b); // 3
The two operators fit together: a == (a / b) * b + a % b always holds, for negative numbers as well. Rust's % takes the sign of the left operand, so -7 % 2 is -1. For a remainder that is never negative, use rem_euclid: (-7_i32).rem_euclid(2) is 1.
Both at once
let quotient = 26 / 3;
let remainder = 26 % 3;
println!("{}", quotient); // 8
println!("{}", remainder); // 2
Check: 8 * 3 + 2 is 26.
Splitting a number into parts
Quotient and remainder together split a quantity into whole units and what is left. To turn 135 seconds into minutes and seconds, the quotient by 60 is the minutes and the remainder is the seconds:
let total = 135;
println!("{}", total / 60); // 2
println!("{}", total % 60); // 15
The same pair answers "how many full boxes?" and "how many items are left over?". The remainder is also how programs test for even numbers: n % 2 == 0 is true exactly when n is even.
The exercise
A product costs price dollars and Andy has amount dollars. He can't buy a fraction of a product, so the answer is the quotient of the amount divided by the price. With 70 dollars and a price of 15, the real quotient is about 4.67, and he can buy 4 products.
The solution in Rust
let amount: i32 = 70;
let price: i32 = 15;
println!("{}", amount / price);
The two i32 values make this an integer division, so the output is 4. The remaining 10 dollars, amount % price, is not enough for another product.
Getting the remainder for free
Because the quotient and the remainder are linked, the remainder can also be computed as amount - amount / price * price. In practice you will simply write %, but the identity is a handy way to check your reasoning: 70 - 4 * 15 is 10, matching 70 % 15. If a result looks off, test it against this identity. It also holds for negative operands, since Rust's truncating division and its % are defined to agree.
Common mistakes
- Dividing by zero.
amount / 0with a zero variable panics with "attempt to divide by zero", in every kind of build. The same goes for%. - Expecting decimals.
7 / 2is 3. Use floats if you need 3.5. - Using floats to count whole items.
70.0 / 15.0prints a long fraction. Cast withas i32to truncate, or keep the values as integers from the start. - Assuming negative results round down. They truncate toward zero.
Key takeaways
- Integer
/gives the quotient, and%gives the remainder. - Rust truncates toward zero; use
div_euclidandrem_euclidfor floor-style results. - Integer and float division are chosen by the operand types, which must match.
