-
Notifications
You must be signed in to change notification settings - Fork 18k
math: remove Compare, Compare32 #60519
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
Comments
The reasoning makes sense to me. I will point out that another reason for |
cmp.Compare does not handle -0 before +0, nor can it do so easily. I am not sure about the need to "solve" #33440. Sort allows equal elements to appear in any order, and -0 == +0 by definition. What is the context where this matters? |
Just that we special-case one float value's comparison (NaN), whereas we allow 0 to follow the language-defined equality. This is more an argument about consistency, than necessity. However this isn't a show-stopper by any means, so I'm in support of this change. |
@dsnet's request in #33440 was "Either this case be documented or we fix the Float64Slice.Less method."
So it seems like this fulfills the original goal of #33440 |
It's perhaps worth pointing out that NaN must be handled as a special case, because the ordinary language comparisons stop being an ordering relationship at all when NaNs are involved, and if you pass an inconsistent ordering relationship to sort, you are very likely not to get sorted results at all. That is, because neither 1 < NaN nor NaN < 1 is true, sort will assume 1 == NaN. But by the same logic it will also assume 2 == NaN and so on. Because sort expects transitivity in the comparison, it may well conclude that 1 == 2 and end up sorting [1, 2, NaN] as [2, NaN, 1] or any other confusing result. Something must be done with NaNs to make sort work at all. (Unless we define that if there are any NaNs anywhere in the input then the entire result of sort is completely undefined.) In contrast, -0 and +0 do not need to be handled as a special case: they are indistinguishable from each other in ordinary operations, and they cause no problems for sort at all. A lesser concern, but it is also true that handling NaNs is very easy and can be done generically (x != x is a simple test for x being a NaN that still does the right thing even when x is not a float at all), while handling -0 vs +0 is not easy and cannot be done generically (the only way to tell them apart is to access the underlying float64 bit patterns, and that cannot be written generically). |
Change https://go.dev/cl/499416 mentions this issue: |
No change in consensus, so accepted. 🎉 |
In #56491 we added math.Compare. The original motivation was:
This need is addressed not only by math.Compare but also by the recently added cmp.Compare.
We ended up with different semantics with respect to NaNs for cmp.Compare and math.Compare. For cmp.Compare we order NaNs all less than negative infinity, the same as sort.Float64s always has. For math.Compare we used the total order predicate from IEEE 754, which sorts NaNs with a negative sign less than negative infinity and NaNs with a positive sign greater than positive infinity. This is strange because NaNs don't even have signs technically, and there's no easy way to get at the sign.
Given that
(1) no one was asking for IEEE 754 NaN total ordering, and
(2) cmp.Compare now addresses the original motivation for math.Compare,
I believe we should remove math.Compare and math.Compare32.
We can always add them back in a future release if someone really does need the IEEE 754 semantics, but we don't have evidence for that today.
The text was updated successfully, but these errors were encountered: