Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounding a f64 to nearest i64 in Rust

Rust's f64 type provides the function round(), which rounds to the nearest integer, but it returns a f64. Java's Math.round(double), on the other hand, returns a long. I can call round() and then cast to i64, but will this guarantee that I get the correct result? Here, "correct" means getting the closest i64 — Java's round() returns the "closest long".

like image 949
yong Avatar asked Dec 14 '16 09:12

yong


Video Answer


1 Answers

From the book, conversions from floating point to integer types round towards zero, so rounding first is nearly correct: f.round() as i64.

However, it's also currently undefined behaviour (but this is a bug) if the f64 is out of range (huge magnitude) of i64. Therefore you should clamp the value first (or possibly better, raise an error or assert). The possibly obvious answer doesn't work:

f.max(std::i64::MIN as f64).min(std::i64::MAX as f64).round() as i64

because the conversions of i64::MAX to f64 aren't exact, and applying the above to 1e100 ends up with a large negative value (in my test; as mentioned it's actually undefined).

The best option seems to be to return an error of some if the floating point value is out of the reasonable range your application expects.

like image 60
Chris Emerson Avatar answered Sep 20 '22 14:09

Chris Emerson