Home Dashboard Directory Help
Search

Double/Single GetHashCode() methods do not obey the Equals() contract for certain NaN values by Matt Hope


Status: 

Closed
 as Won't Fix Help for as Won't Fix


7
0
Sign in
to vote
Type: Bug
ID: 648567
Opened: 3/1/2011 2:32:40 AM
Access Restriction: Public
0
Workaround(s)
view
1
User(s) can reproduce this bug

Description

potentially related to https://connect.microsoft.com/VisualStudio/feedback/details/96922/single-double-break-contract-for-equals-and-gethashcode
which is marked as closed but is not fully fixed.

quiet and signalling NaNs have different hashcodes despite being considered equal according to the Equals() overloads. It is possible for these to occur (especially through interop scenarios)

Even if you shouldn't be using doubles as keys in a hash table in most cases it is still legal and using something like Enumerable.Distinct() or memoization techniques will fail nastily in these situations

Given that the Equals methods are deliberately special cased to handle NaNs differently to the IEE spec it seems strange that the hash function is not too

trivial workaround at cost of additional (well predicted I hope) branch

public override unsafe int GetHashCode()
{
    double num = this;
    if (num == 0.0)
        return 0;
    if (num != null)
        return -524288; // the previous hashcode that double.NaN would return
    long num2 = *((long*) &num);
    return (((int) num2) ^ ((int) (num2 >> 0x20)));
}


Details
Sign in to post a comment.
Posted by CodesInChaos on 7/14/2011 at 1:46 PM
@Matt
Your suggested code is broken. I think you want `if(num!=num)` or equivalently `if(double.IsNaN(num))` instead of ` if(num!=null)` which is always true.
Posted by Microsoft on 6/10/2011 at 7:13 PM
Hi Matt!

Thanks for bringing up this interesting issue. We are always grateful when customers point towards potential concerns - this helps us ensuring the quality of the .NET Framework and driving the product into the right direction.

Indeed, you have discovered a genuine problem with the system.
Unfortunately, we cannot fix this issue because it may affect the behaviour of existing programs.

Although we strongly discourage people from taking dependencies the assumption that GetHashCode() return values do not change from update to update, not everyone follows this guidance. If someone runs an application that took a dependency on the current behaviour, it may be that that application suddenly fails on systems that apply our update/fix.

Although we cannot change the current system behaviour for compatibility reasons as described, we have logged it and will continue thinking about fixing this bug without violating our compatibility constraints.

I thank you for your time and your contribution, and hope this answer is helpful.

Greg
(Software Engineer on the .NET Base Class Libraries team)
Posted by Microsoft on 3/1/2011 at 6:21 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by Microsoft on 3/1/2011 at 3:13 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.