Skip to content
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

Handle NaN in value comparers for double/float #22168

Merged
merged 1 commit into from
Aug 25, 2020
Merged

Conversation

roji
Copy link
Member

@roji roji commented Aug 21, 2020

Fixes #22167

@roji
Copy link
Member Author

roji commented Aug 21, 2020

Note: this does add the NaN check for all databases, including those which don't support it. If we think that's significant we can just have the comparers and leave it to providers to use them.

Copy link
Contributor

@bricelam bricelam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ajcvickers
Copy link
Member

@AndriySvyryd Any Cosmos changes needed here to handle NaN?

@AndriySvyryd
Copy link
Member

@AndriySvyryd Any Cosmos changes needed here to handle NaN?

Yes. But I don't think it's high enough of a priority

@roji
Copy link
Member Author

roji commented Aug 25, 2020

In triage we mentioning possibly having core-level floating point mappings with the right comparer, but I see we have no mappings at all in core. I've put the comparers themselves in core, so it's trivial for any non-relational provider to use them if they want, am going to go ahead and merge as-is.

@roji roji merged commit 9451b9c into release/5.0 Aug 25, 2020
@roji roji deleted the NaNNaNNaNNaNNa branch August 25, 2020 08:05
/// Initializes a new instance of the <see cref="DoubleValueComparer" /> class.
/// </summary>
public DoubleValueComparer() : base(
(x, y) => double.IsNaN(x) ? double.IsNaN(y) : x.Equals(y),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it's merged now, but

Suggested change
(x, y) => double.IsNaN(x) ? double.IsNaN(y) : x.Equals(y),
(x, y) => x.Equals(y),

will yield the same result.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, did not know that... Do you want to submit a cleanup PR for this (and the same for FloatValueComparer)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, will send one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--> #22212

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the value comparer are just doing Equals then do we need a custom value comparer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @smitpatel. What's the actual issue we're trying to fix here?

Copy link
Member Author

@roji roji Aug 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what's happening.

  • The result of double.NaN == double.NaN is false, but the result of double.NaN.Equals(double.NaN) is true.
  • Previous to this PR, floating point properties would get a default ValueComparer, whose implementation of Equals is Expression.Equal. That calls the "operator" version which returns false.
  • This PR (and DoubleValueComparer / FloatValueComparer cleaned up NaN-handling #22212) fixes that by having a specialized value comparer which calls double.Equals instead of ==, which works correctly.

It may be better to fix this by having a DefaultDoubleValueComparer which is the same as DefaultValueComparer, but calls Equals instead of ==: it's cleaner and would work universally (e.g. Cosmos). @ajcvickers if that makes sense I'll submit that. If we don't do that, we probably want to clean up and remove double/float from DefaultValueComparer as it doesn't work correctly for NaN.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roji Yes, do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roji maybe it makes sense to close #22212 and incorporate that change into your coming PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gfoidl, submitted #22242 to clean this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle NaN in value comparers for double/float
6 participants