Step 5 of 7
Converting types with as
Rust never converts one number type into another behind your back: a + b with an i32 and an f64 doesn't compile. You convert explicitly with the keyword as:
fn main() {
let total_points: u32 = 17;
let games: u32 = 4;
let average = total_points as f64 / games as f64;
println!("integer division: {}", total_points / games);
println!("float division: {average}");
}
integer division: 4
float division: 4.25
as happens before arithmetic, so total_points as f64 / games as f64 converts both sides, then divides.
What as does in each direction
fn main() {
println!("{}", 3.99_f64 as i32);
println!("{}", -3.99_f64 as i32);
println!("{}", 300.7_f64 as u8);
println!("{}", 300_i32 as u8);
println!("{}", -1_i32 as u32);
println!("{}", 65_u8 as char);
}
3
-3
255
44
4294967295
A
- Float to integer drops the fraction (toward zero) and clamps to the target's range: 300.7 becomes 255, the largest
u8. - Integer to a smaller integer keeps only the low bits, which wraps: 300 becomes 44 (300 - 256).
- Signed to unsigned: -1 becomes the largest
u32. u8tochargives the character with that code: 65 isA.- To a bigger type (
u8tou32,i32toi64,i32tof64): the value is kept exactly.
So as never fails, but it can silently change a value when the target can't hold it. To round instead of truncate, round first: 2.7_f64.round() as i32 is 3.
At work: as is everyday code for widening conversions and for turning integers into floats to do math. For conversions that might lose data, idiomatic code uses try_from, which reports failure instead (a later module), and clippy's stricter lint group (clippy::pedantic) flags risky casts.
Common mistakes
Converting only one side doesn't compile, because the two sides of / must have the same type:
fn main() {
let total_points: u32 = 17;
let games: u32 = 4;
let average = total_points as f64 / games;
println!("{average}");
}
error[E0277]: cannot divide `f64` by `u32`
--> src/main.rs:4:39
|
4 | let average = total_points as f64 / games;
| ^ no implementation for `f64 / u32`
- Converting after dividing:
(17 / 4) as f64is4.0, because the integer division already threw the fraction away. Convert before dividing. - Expecting rounding:
2.99 as i32is2. Round first if that's what you mean.
Your task
A student got 7 of 9 questions right. Convert both to f64, compute the percentage, and print it with two decimals: Score: 77.78%.
Challenge 2
Fill in the blanks so both integers are converted to floats before dividing, and the program prints 2.5.
Challenge 3
A temperature sensor reports -3.7 degrees, but a small display shows whole numbers. Print the reading three ways, one per line: cast directly with as i32 (truncates), rounded and then cast, and the original float with one decimal:
-3
-4
-3.7