If I have a couple of floating-point numbers and try to sort them like this:
fn main() {
let mut nums: Vec<f64> = vec![0.53, 3.18, 4.783, 9.0, -1.2, 0.0];
nums.sort();
println!("{:?}", nums);
}
I get a compile error: "the trait bound f64: Ord
is not satisfied".
How can I sort these numbers?
TLDR: do
nums.sort_by(f64::total_cmp);
The basic reason why Rust doesn't let you sort floating-point numbers is that NaN
is weird. All comparisons involving a NaN
return false
, which can cause sorting algorithms to break (this is an issue in Python, for example). There's also the strange case of zero and negative zero, which are equal yet have different representations. Since Rust's design philosophy revolves around handling errors explicitly, you cannot use the sort()
method on floats.
However, IEEE 754 does define a way to sort floating-point numbers which can handle any kind of NaN
(there are many bit patterns which represent a NaN
). The order is:
NaN
(negative sign bit), in descending order of the significand bitsNaN
(positive sign bit), in ascending order of the significand bitsTo get this ordering, Rust offers the total_cmp method between all the float types. Therefore, your code can be fixed by doing:
fn main() {
let mut nums: Vec<f64> = vec![0.53, 3.18, 4.783, 9.0, -1.2, 0.0];
nums.sort_by(f64::total_cmp);
println!("{:?}", nums);
}