sortingrustfloating-point

How can I sort a vector of floats in Rust?


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?


Solution

  • 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:

    To 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);
    }
    

    (playground link)