The five operators
Rust does arithmetic with five operators. They work on numbers written directly in the code and on variables that hold numbers.
| Operator | Name | Example | Result |
|---|---|---|---|
+ | addition | 2 + 6 | 8 |
- | subtraction | 10 - 7 | 3 |
* | multiplication | 3 * 3 | 9 |
/ | division | 6 / 2 | 3 |
% | remainder | 8 % 3 | 2 |
To see a result you print it. println!("{}", expression) evaluates the expression and puts its value where the {} placeholder is:
let a = 2;
let b = 3;
println!("{}", a + b); // 5
println!("{}", a - b); // -1
println!("{}", 2 * a * b); // 12
println!("{}", 10 - b); // 7
Using a variable in a calculation doesn't change it. After a + b, a is still 2. A variable changes only when you assign to it, and in Rust that also needs the variable to be declared with let mut.
Division of integers
When both operands are integers, / returns an integer: the fractional part is dropped, and the quotient is rounded toward zero.
let a = 2;
let b = 3;
println!("{}", 20 / 3); // 6
println!("{}", b / a); // 1
println!("{}", -7 / 2); // -3
To get a fractional answer, use floating-point numbers. Write a literal with a decimal point, or convert a variable with as f64:
let a = 2;
let b = 3;
println!("{}", 7.0_f64 / 2.0); // 3.5
println!("{}", b as f64 / a as f64); // 1.5
as binds tighter than /, so b as f64 / a as f64 converts each variable first and then divides.
The remainder operator
The % operator gives what is left over after a division. Since 8 contains two whole 3s with 2 left over, 8 % 3 is 2. It pairs with integer division: for positive numbers, (a / b) * b + a % b always gives back a. The remainder is 0 exactly when the division is exact, which makes n % 2 == 0 the usual test for an even number.
println!("{}", 26 / 3); // 8
println!("{}", 26 % 3); // 2
println!("{}", 10 % 2); // 0
With a negative left operand the remainder takes the sign of that operand: -7 % 2 is -1.
Rust does not mix integers and floats
Many languages quietly convert an integer to a float when you combine them. Rust doesn't. Both operands must have the same type, and a mismatch is a compile error:
let price: f64 = 70.0;
let count: i32 = 4;
let total = price * count; // error[E0277]: cannot multiply `f64` by `i32`
The fix is an explicit conversion: price * count as f64. The same rule applies to integer variables of different widths, such as i32 and i64.
Overflow
An i32 holds values up to 2147483647. Going past that is overflow. In a debug build (cargo run without --release) it panics, while in an optimized build (rustc -O, --release) the result silently wraps around to a negative number. Either way the answer is not what you meant, so pick a wider type such as i64 when values can get large.
The exercise
The variable price holds the cost of one product. Andy buys 4 products at that price and one bag for 15 dollars, and the program must print what he pays in total.
- Multiply the price by the quantity:
4 * price. - Add the bag:
+ 15. - Print the whole expression through
println!with a{}placeholder.
Multiplication is evaluated before addition, so no parentheses are needed. With price equal to 83, the product part is 332 and the total is 347.
The types line up on their own: price is an i32, so the literals 4 and 15 are read as i32 too, and the result is an i32. If price were declared as f64, the literals would have to be written 4.0 and 15.0.
The solution in Rust
let price: i32 = 83;
println!("{}", 4 * price + 15);
The format string comes first and the value follows after a comma. The value is not part of the string: println!("4 * price + 15") would print that text literally.
Common mistakes
- Expecting
7 / 2to be 3.5. With integers it is 3. Use7.0 / 2.0for 3.5. - Mixing
f64and integer types.2.5 * 4does not compile; write2.5 * 4.0. - Dividing by zero. Integer division or remainder by zero panics at run time, in every kind of build.
- Forgetting the quotes or the placeholder.
println!(4 * price)is an error: the first argument must be a string literal.
Key takeaways
+,-,*,/and%work on numbers and variables, and don't change the variables.- Integer
/drops the fraction; floats keep it. - Both sides of an operator must have the same numeric type.
println!("{}", expression)prints the value of an expression.
