-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Improve floating point IEEE Ordering consistency #8622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Make `Ordering#compare(0.0, -0.0)` consistent with the IEEE specification for floating point `Ordering`s.
What about IMO this painfully highlights that an I would go as far as deprecating |
Yup. There's unfortunately not anything to do about that. I think the current behavior is the best we can get.
trait FloatIsFractional extends Fractional[Float] {
// ...
}
implicit object FloatIsFractional extends FloatIsFractional with Ordering.Float.IeeeOrdering I don't remember why we decided to do that; the best I can come up with are these two comments: |
@sjrd - The problem is that we have an insufficient number of abstractions: we only have IEEE754 insists that Because we don't have In other words, one would think that all these things are true: a max b == Seq(a, b).max
a min b == Seq(a, b).min
Seq(a, b).sorted.map(_.toString) == Seq(b, a).sorted.map(_.toString) but they can't be with the same rules on how floating-point numbers compare, and we have only a single abstraction instead of two. |
at the end of the day, whatever we decide to do wrt the default ordering and the structure of the library, this is a strict improvement to IEEE orderings imo |
@NthPortal - But (Aside: we can declare |
and it does. a total ordering does not require that equivalent elements be identical, afaik (or if you think of it differently, |
@NthPortal - Right, a total ordering can have equivalence classes. And you can declare a total ordering that does not respect the equivalence classes defined by some alternate ordering. My point, though, is that the same total order that declares that -0.0 comes before 0.0 also declares that -qNaN < -sNaN (all of them) < actual numbers < sNaN (all of them) < qNaN, but we're not doing that; instead we're grouping all the NaNs into a single equivalence class. The other one, which isn't a total order, declares that 0.0 and -0.0 are equal, and doesn't say where NaN should go if you sort them. Since we don't sort NaN where they say to, I don't think it's correct that having -0.0 before 0.0 agrees better with IEEE754; it just makes us try to agree more with the IEEE754 total ordering, which we already fail at. |
We need to decide whether to merge this for 2.13.2. It appears to me that it is mergeable, or not, separately from the other open @NthPortal do you want to respond to Rex's last comment? @Ichoran I confess to not understanding your last comment. in particular, I'm not able to follow the thinking behind "Since we don't sort NaN where they say to, I don't think it's correct that having -0.0 before 0.0 agrees better with IEEE754". as it stands, @NthPortal's "this is a strict improvement to IEEE orderings imo" is also where I stand... unless you can make your objection crystal-clear? |
@SethTisue - My argument is as follows. IEEE754 defines the behavior of a IEEE754 also defines a total ordering over all bit patterns that can appear: a particular sequence of This total ordering is dramatically different from what Java does for sorting, which is based on By having So we add mandatory extra computation on every compare, but still don't give either the IEEE total ordering or agreement with Adding a likely runtime penalty for all Before, Before, Before, I just don't see this as better in any meaningful way. It's different. And possibly slower, which is always bad for things like this, so should be tested. |
@Ichoran I understand. Thank you. Also, I'm increasingly convinced that we shouldn't be changing the runtime behaviors anymore in 2.13.x unless they're Just Plain Wrong. Whether Rex's argument would convince me for a 2.14 or 3.0 decision, I don't know. But in the 2.13.x context, it's enough: I'm convinced this would be a design change and not just a bugfix. |
Make
Ordering#compare(0.0, -0.0)
consistent withthe IEEE specification for floating point
Ordering
s.I randomly noticed this was not consistent with the IEEE spec (or with
lt
,gt
, etc.), but could be.