Floor and cast f64 to usize in one operation

I have the following example code:

let exact_range: f64 = 42.6;
let range1: usize = exact_range.floor() as usize;

Is there a method somewhere in the standard library that does floors a f64 float and returns a usize directly? I see the as usize not as inherently unsafe, but bug-prone, since I could also call exact_range as usize directly (not sure how that would convert float to int tbh). And since the floor method always returns an "integer" (float ending in .0), I thought there would be a floor method that directly returns a usize or any other integer with enough bits (so not a u8 or something).

There is no primitive integer type with enough bits to represent all possible intger-valued floats. An f64 has a maximal finite value of more than 10308, which would require an approximately 900-bit integer to accomodate.


Searching through the documentation it doesn’t seem like there is.
It also seems difficult to implement, because the integer range of f64 is much greater than usize.
Additionally, floats can have weird values like ±∞ or NaN which this method needs to deal with.

fNN as iNN is defined to be a truncating cast, saturating out-of-range values and mapping NaN to 0. If that's what you want, just writing as is currently the best way to get that behavior.

Documentation for this was merged into the reference by Account for removal of UB in float-to-int casts by Mark-Simulacrum · Pull Request #810 · rust-lang/reference · GitHub


One exception, u128 is big enough for all positive finite f32 values, i.e. u128::MAX > f32::MAX.

1 Like

That's correct, but I believe OP was asking about f64 specifically. (Also, usize is not guaranteed to be 128 bits wide, so it can't be relied on either.)

Ok, so seems like what I'm doing right now seems reasonable (for a small cli tool). Just wanted to make sure I'm not missing some alternate solution. Thanks for the help!