Step 4 of 7
Floating-point numbers
Numbers with a fractional part are floating-point numbers, or "floats". Rust has two: f64 (64 bits, about 15 to 16 significant digits, the default) and f32 (32 bits, less precise, used in graphics and games where memory matters). Use f64 unless you have a reason not to.
A float literal needs a decimal point: 2.0, not 2.
fn main() {
let price = 19.99;
let quantity = 3.0;
let total = price * quantity;
println!("{total}");
println!("{:.1}", total);
println!("{}", 7.0 / 2.0);
}
59.97
60.0
3.5
Rounding in the output
{:.2} prints a float rounded to 2 digits after the decimal point; {:.0}, {:.1} and {:.3} work the same way. It combines with a name: {total:.2}. Only the printed text is rounded; the value itself doesn't change.
Floats are approximate
Floats are stored in binary, and most decimal fractions (like 0.1) can't be stored exactly, just as 1/3 can't be written exactly in decimal:
fn main() {
let sum = 0.1 + 0.2;
println!("{sum}");
println!("{sum:.2}");
}
0.30000000000000004
0.30
Two consequences you'll meet at work:
- Don't compare floats with
==after calculations; check whether they're close enough instead. - Don't store money in floats. Payment systems store amounts as whole cents in an integer type and only format them as dollars for display.
Float division by zero doesn't panic: 1.0 / 0.0 is inf (infinity), and 0.0 / 0.0 is NaN ("not a number").
Useful float methods
fn main() {
let x: f64 = 2.0;
println!("{:.4}", x.sqrt());
println!("{}", x.powi(10));
let temperature: f64 = -7.5;
println!("{}", temperature.abs());
println!("{}", 2.567_f64.round());
println!("{}", 2.567_f64.floor());
}
1.4142
1024
7.5
3
2
sqrt is the square root, powi(10) raises to a whole-number power, abs drops the sign, round rounds to the nearest whole number and floor rounds down. Notice that {} prints a float with no fractional part as 3; {:?} would print 3.0.
Common mistakes
Rust won't mix integers and floats in arithmetic:
fn main() {
let total = 5 + 2.5;
println!("{total}");
}
error[E0277]: cannot add a float to an integer
--> src/main.rs:2:19
|
2 | let total = 5 + 2.5;
| ^ no implementation for `{integer} + {float}`
Write 5.0 + 2.5, or convert the integer (coming next).
- A method on an unannotated float:
let x = 2.0; x.sqrt()giveserror[E0689]: can't call method `sqrt` on ambiguous numeric type `{float}`. The compiler doesn't know yet whetherxisf32orf64; writelet x: f64 = 2.0;. - Minus signs and methods:
-7.5_f64.abs()is-7.5, because the method runs before the minus: it means-(7.5_f64.abs()). Use a variable or parentheses:(-7.5_f64).abs().
Your task
Three test scores are 81.0, 92.5 and 77.25. Print their average rounded to two decimals: Average: 83.58.
Challenge 2
Fill in the format so the price prints with exactly two decimals: Price: 4.50.
Challenge 3
A circular arena has a radius of 2.5 meters. Print its area (π times the radius squared) with three decimals: Area: 19.635. Rust has π built in as std::f64::consts::PI (a path into the standard library, std).
Previous: When numbers overflow Next: Converting types with as