🎓 A1Learner
🔍

Rust Float Methods

Float methods are operations that belong to decimal numbers. Float methods can split a value into whole and fractional parts.

Keep the part after the point: fract

trunc keeps the whole part, fract keeps the rest. For a negative number, the fraction keeps its sign:

let x = 3.75f64;
println!("whole = {} part = {}", x.trunc(), x.fract());
let y = -3.75f64;
println!("neg part = {}", y.fract());

Two ways to round a half

round sends a half away from zero, so 2.5 becomes 3. round_ties_even sends it to the even neighbour, so 2.5 becomes 2. Over many roundings, the halves cancel out instead of piling up:

println!("{} {}", 2.5f64.round(), 3.5f64.round());
println!("{} {}", 2.5f64.round_ties_even(), 3.5f64.round_ties_even());

Keep a value in range: clamp

clamp gives back the value, or the nearest edge when the value strays outside:

let speed = 87.5f64;
println!("limited = {}", speed.clamp(0.0, 60.0));
println!("low = {}", (-4.0f64).clamp(0.0, 60.0));

The bigger and smaller of two: max and min

Floats offer max and min as methods. A NaN quietly loses: the real number is returned:

println!("bigger = {}", 3.5f64.max(7.25));
println!("smaller = {}", 3.5f64.min(7.25));
println!("nan loses = {}", f64::NAN.max(2.0));

Ask about the sign

Two checks read the sign of a float. Even zero carries a sign: -0.0 compares equal to 0.0, yet its sign bit says negative:

println!("{} {}", 4.5f64.is_sign_positive(), (-4.5f64).is_sign_positive());
let minus_zero = -0.0f64;
println!("equal = {} but sign negative = {}", minus_zero == 0.0, minus_zero.is_sign_negative());

Angles: degrees and radians

Trigonometry in Rust works in radians. Two methods change units, so you can think in degrees and compute in radians:

use std::f64::consts::PI;
println!("half turn = {} degrees", PI.to_degrees());
println!("90 degrees = {:.4} radians", 90.0f64.to_radians());

The long side of a triangle: hypot

hypot works out the square root of a² + b² carefully. Even very large sides do not overflow on the way:

let a = 3.0f64;
let b = 4.0f64;
println!("long side = {}", a.hypot(b));

Example

fn main() {
    let reading = 23.86f64;
    println!("whole degrees = {}", reading.trunc());
    println!("tenths part = {:.2}", reading.fract());
    let shown = reading.clamp(0.0, 20.0);
    println!("display capped = {}", shown);
    let angle = 45.0f64;
    println!("45 degrees in radians = {:.4}", angle.to_radians());
    let dx = 6.0f64;
    let dy = 8.0f64;
    println!("distance = {}", dx.hypot(dy));
}

Key points

  • Use clamp(min, max) to keep a float inside a range.
  • It panics if min is bigger than max.
  • It also panics if a bound is NaN.
  • In short, float methods are small operations built into decimal numbers.

In this example, a sensor reading of 23.86 is taken apart three ways. trunc keeps the whole degrees, 23. fract keeps the part after the point. It prints as 0.86. The display cannot show more than 20. So clamp caps the reading at the top edge. The value itself is untouched. Only the copy in shown is limited. Then an angle of 45 degrees becomes 0.7854 radians, the unit Rust maths expects. Last, hypot turns the two legs of a walk, 6 and 8, into the straight-line distance: 10.

Note

powi raises a float to a whole-number power and is faster. powf takes a float power.

The Floating Point lesson used powf.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

What does 2.5f64.round_ties_even() return?