It's job is to represent a "23-bit Int" via Floating point.
How do I implement <, >, Ord, PartialOrd on the struct above?
=====
Why aren't you just using a i32 ? Because this is representing data for a WebGL buffer, and it turns out, as documented in WebGLRenderingContext.vertexAttribPointer() - Web APIs | MDN that the only supported types are float, short, ushort, byte -- no i32.
Although, upon some testing, it seems that a 32 bit float can accurately represent every value from 0..(2 ^ 23), so I think that just using some casting would be okay instead of bit-reinterpretation.
Problem I was running into: apparently Eq is not implemented for f32 in Rust -- as a result, I need to use ParitialEq + PartialOrd, but AVOID Eq and Ord.
That's specified in the IEEE 754 standard (otherwise known as ISO/IEC/IEEE 60559:2011), due to NaNs, which are specified to never compare equal to anything, even themselves. Thus the requirements of Eq cannot be satisfied.
Rust has nothing to do with that constraint, except that Rust conforms to the international floating-point standard.
I absolutely think it does, and would love for someone motivated to pick up this PR and drive the "which form should it take?" conversation to a conclusion:
I don't see how it is mathematically possible to resolve this:
Ord requires Eq.
According to Eq in std::cmp - Rust , Eq is required to be Equivalence Relation, which implies that for all values f: f32, we have "f == f", this includes having "NaN == NaN"
Yet, on the other hand, IEEE standard requires that "NaN != NaN".
The IEEE-754 "Total ordering" thing doesn't really have anything to do with your problem, but it is entirely possible to write a struct TotalOrder(f64) that implements Ord, or for std to provide an inherent method f64::total_order_cmp(self, other: f64) -> Ordering.
and within each class, order is determined by comparing sign * payload.
You have to understand, the totalOrder predicate is different from the default ordering scheme of floats. It's not even compatible; for instance, the totalOrder predicate specifies that -0.0 < 0.0, and does not consider different representations of the same value to be equal.
Theyall return Ordering::Equal This is possible because only f64::cmp() promises to fulfill the IEEE-754 specification, but not f64::total_order_cmp().
That is, it compares the payload of the NaNs (the 51 bits of the mantissa that don't include the signaling/quiet bit), and inverts the comparison if they are negative.