Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Float type that implements `Eq` in rust

In rust, is there a version of f32 / f64 that implements Eq?
The only reason I can see for f32 / f64 not implementing Eq is that NaN != NaN.
Potential ways such a type could behave:

  1. The type could just make NaN == NaN for that type which would be really useful because I often assume that a == a is always true.
  2. Another approach would be to disallow NaN entirely in that type so that there is no NaN that could be unequal to itself.

Ideally there would be a way to use that type just by using a suffix (similar to 2.3_f32) but I don't think that is possible.

like image 706
MarcellPerger Avatar asked Aug 07 '26 06:08

MarcellPerger


2 Answers

Since Rust 1.62.0, you can use the total_cmp() methods of f32 and f64. Not a type on their own, but you can build a type on top of them if you want.

Or you can use the ordered-float crate. It provides the NotNan and OrderedFloat types, each matching one behavior you described.

like image 85
Chayim Friedman Avatar answered Aug 10 '26 12:08

Chayim Friedman


f64 and f32 cannot implement Eq, because of Rust's fundamental design mistake of making Eq a sub-type of PartialEq.

This means that despite the IEEE754 spec defining a total order for floating point values, there can only ever be a single implementation inside Rust's Eq-PartialEq hierarchy.

That implementation uses the comparison predicate (which is only a partial order), instead of the total-order predicate (which is a total order (and therefore a partial order as well)).

If Eq and PartialEq were unrelated, floating point types could implement both §5.10 for Eq and §5.11 for PartialEq – but because they aren't – Rust was forced to pick one, and it chose §5.11.

In that world you'd also have picked less confusing names for PartialEq and Eq.

like image 41
soc Avatar answered Aug 10 '26 14:08

soc