Max value of an integer variable could hold

let num_elements: u16 = 42;

Let's say I have a variable of some integer type. How can I get the maximum value it could hold without writing out its type name? It's u16 now but I don't want to hardcode that downstream. Is there an expression that will resolve to u16::MAX if it's a u16, isize::MAX if it's an isize, etc.?

I know I could could use a type alias:

type ElementCount = u16;
let num_elements: ElementCount = 42;
    
let max_elements = ElementCount::MAX;
println!("num_elements can be at most {}", max_elements);

But it's clunky. Is there a more direct way, something like this?

let max_elements = num_elements.MAX;  // doesn't work
println!("num_elements can be at most {}", max_elements);

With something like Bounded in num_traits::bounds - Rust you can write Bounded::max_value(). Of course, adding a dependency just for this might be overkill.

4 Likes

What do I write exactly, how does num_elements fit in? Bounded::max_value() has no receiver.

use num_traits::bounds::Bounded;

trait MinMax: Bounded + Sized {
    fn min_value_of_type(&self) -> Self {
        <Self as Bounded>::min_value()
    }
    fn max_value_of_type(&self) -> Self {
        <Self as Bounded>::max_value()
    }
}

impl<T: Bounded> MinMax for T {}

fn main() {
    let n = 1;
    assert_eq!(n.max_value_of_type(), i32::MAX);
    assert_eq!(2u64.max_value_of_type(), u64::MAX);
}

playground

1 Like

In my own opinion, I think you should stick with the first code since it works. Calling method mostly in rust is achieved using this :: , bringing in extra crate will surely increase the size of the program.

1 Like

Well, depending on the use-case, it might already be the case that type inference helps you out. Though, admitted, num-traits is more for the case where you’re writing an actually generic function, rather than for your use-case of easily refactorable choice of type (and in this case, you’d have a generic type parameter T: Bounded or T: PrimInt or something like that, and could explicitly write T::max_val()); IMO defining a type alias such as type ElementCount = u16; is a very decent approach for this.

3 Likes

You can use mathy shenanigans... but I don't really recommend it.

macro_rules! max_value {
    ($e:expr) => {{
        let ones = !($e * 0);
        let shifted = (ones - 1).rotate_right(1);
        ones.max(shifted)
    }}
}

I too think the type alias is the way to go. You'll also hate yourself less if you do change it later (unless your IDE is good enough to do it for you, in which case why not use u16::MAX too). The main downside is forgetting what it is when you come back to the code later.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.