You could even say the reason NaN exists is so that you don't have to check for NaN constantly. Rust is being technically correct but practically really annoying, for basically no benefit.
It is not something to use by default though. It is implemented in software and thus a lot slower than the hardware comparison.
But fortunately in comparison sort algorithms that run in O(n lg n) you can get away with doing an O(n) partitioning of the array into [-, +, NaN] and then applying a fast integer comparison operator to the negative values (-) and positive values (+).
In fact the above idea ties in neatly with QuickSort, which is already based on partitioning & sorting recursively.
Is this true?
I am actually struggling to remember the last time I did a sort with a float/double as the key--especially in a performance bounded context
... <thinking> ...
Aha. Graphic engine. Octtree with coordinates.
I really had to think about that.
So, I'm a bit skeptical of float sorting happening a "lot".
Is this perhaps an ML primitive somewhere?
So since no one needs this often enough to emit the soft-float comparison code, we should emit the fast code. If folks need different behavior they should use different types. This is similar to the behavior with integer overflow, which you can opt into by using checked types or checked operations. Though in rust we have a convenience that the overflow-detecting code is emitted for debug targets.
This is often a Bad Idea, as you get unstable sorts and you are right back to the same problem.
- Explanation: How do I get the minimum or maximum value of an iterator containing floating point numbers? — https://stackoverflow.com/a/50308360/155423
- Example: https://play.integer32.com/?version=stable&mode=debug&editio...
See also:
- How to do a binary search on a Vec of floats? — https://stackoverflow.com/q/28247990/155423
Instead, use a wrapper type or raise a panic.