Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit float value to min/max range in Rust

Tags:

rust

Given some arbitrary float value, what's an idiomatic way of limiting that value to a min/max range? I.e. if you provide a value under the minimum, the minimum range value is returned, and if you provide a value over the maximum, the maximum range value is returned. Otherwise the original float value is returned.

I thought this approach would work, but it's not giving me the correct values:

fn main(){
    dbg!(min_max(150.0, 0.0, 100.0));
    //because 150.0 is greater than 100.0, should return 100.0
    //currently returns 0.0
    dbg!(min_max(-100.0, 0.0, 100.0));
    //becuase -100.0 is below the minimum value of 0.0, should return 0.0
    //currently returns 0.0
}

fn min_max(val: f32, min: f32, max: f32)->f32{
    return val.max(max).min(min);
}    

Playground

like image 415
ANimator120 Avatar asked May 13 '26 14:05

ANimator120


2 Answers

pheki's answer explains why your attempt didn't work, but there's also a method dedicated to this task: clamp.

fn main(){
    dbg!(150.0_f32.clamp(0.0, 100.0));     // = 100.0
    dbg!((-100.0_f32).clamp(0.0, 100.0));  // = 0.0
}

(The added _f32 suffixes are required to tell Rust that we want to use f32 numbers instead of possibly f64 — the program won't compile otherwise. They're only necessary in this tiny example because there are no function signatures or anything else which specifies which type we want to use.)

like image 176
Kevin Reid Avatar answered May 15 '26 18:05

Kevin Reid


You're almost correct, but it's actually the opposite:

fn main(){
    // Because 150.0 is greater than 100.0, returns 100.0
    dbg!(min_max(150.0, 0.0, 100.0));
    // Because -100.0 is below the minimum value of 0.0, returns 0.0
    dbg!(min_max(-100.0, 0.0, 100.0));
    // Because 70.0 is in-between, returns itself
    dbg!(min_max(70.0, 0.0, 100.0));
}

fn min_max(val: f32, min: f32, max: f32)->f32{
    return val.min(max).max(min);
}    

Since max always returns the MAXIMUM between two numbers (based on the max math function), you're actually setting a MINIMUM output value, as if the other value is lower, this one will be chosen, for example:

  • The maximum between 150 and 100 is 150. 150f32.max(100.0) == 150
  • The maximum between 50 and 100 is 100. 50f32.max(100.0) == 100

The same logic applies to min, it can be used to set a maximum value.

like image 36
pheki Avatar answered May 15 '26 19:05

pheki