ANimator120
ANimator120

Reputation: 3401

Limit float value to min/max range in 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

Upvotes: 9

Views: 7458

Answers (2)

Kevin Reid
Kevin Reid

Reputation: 43753

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.)

Upvotes: 13

pheki
pheki

Reputation: 632

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.

Upvotes: 4

Related Questions