-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[API Proposal]: Modify Float/Double Equals and CompareTo to reflect -0.0 and +0.0 difference and ordering #73583
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
@tannergooding, this is the issue I opened as a result of our discussion. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsBackground and motivationIEEE 754 states that mathematical operations should consider -0.0 and +0.0 to be equal. The behavior of comparison methods such as .Equals and .CompareTo are not defined by IEEE 754. We already have precedent as .Equals and .CompareTo have different behavior than ==,>, and < when comparing NaN. Today if you have a list of doubles in an array which includes -0.0 and +0.0, calling API ProposalN/A as this is a proposal for a change in behavior with no public surface changes. API UsageN/A Alternative DesignsAn alternative is to provide new static properties on Float and Double which provide instances of RisksIf code is consuming doubles or floats and using .Equals to compare them with 0.0, values which represent negative zero would now return false.
|
This is worth taking to API review for consideration. IEEE 754 has a concept of "total order" and this is exposed in certain api's such as The exact semantics it describes are:
In .NET, we don't really have a concept of ============== If API review deems this change would be too breaking, we should investigate what alternatives we can provide to help provide a concept of overall ordering, such as a Several languages provide a concept of |
Q: Within the space of, say -qNaNs, are they all expected to sort as equals? or do we sort by their significands? |
The IEEE 754 |
It means that the non-deterministic behavior of sorting is not going to be fully fixed by this proposal.
Another alternative design to switch to a stable sorting algorithm in the BCL that would fix this whole class of problems for good. |
namespace System.Numerics;
public struct TotalOrderIeee754Comparer<T> : IComparer<T>, IEqualityComparer<T>
where T : IFloatingPointIeee754<T>
{
// all the methods required by those interfaces
} |
Shouldn't we also add an |
We opted for no |
Oh, it's a struct, didn't see. |
Background and motivation
IEEE 754 states that mathematical operations should consider -0.0 and +0.0 to be equal. The behavior of comparison methods such as .Equals and .CompareTo are not defined by IEEE 754. We already have precedent as .Equals and .CompareTo have different behavior than ==,>, and < when comparing NaN.
Double.NaN == Double.NaN
evaluates to false (as per IEEE 754), butDouble.NaN.Equals(Double.NaN)
evaluates to true. The CompareTo has similar behavior where it returns 0 to indicate they are the same.Today if you have a list of doubles in an array which includes -0.0 and +0.0, calling
Array<double>.Sort()
is non-deterministic. The order of -0.0 and +0.0 will depend on the initial order of the array elements, Even with the same order, the resulting order is potentially fragile from one release of .NET to the next as the algorithm used for sorting is an internal implementation detail and could be changed between releases.API Proposal
N/A as this is a proposal for a change in behavior with no public surface changes.
API Usage
N/A
Alternative Designs
An alternative is to provide new static properties on Float and Double which provide instances of
IComparer<T>
andIEqualityComparer<T>
with this different behavior which can be provided to collections and method calls to order the zero values.Risks
If code is consuming doubles or floats and using .Equals to compare them with 0.0, values which represent negative zero would now return false.
There will be a small performance regression in some cases as extra comparisons will need to be made. This should be able to be minimized with careful coding. We would only need to do a zero check if
==
returns true which will usually not be the case with floating point numbers.The text was updated successfully, but these errors were encountered: