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
10 years old bug that migrated from .net to .net core. (System.Value.Equal) #8028
Comments
@karelz Anyone working on this? I'd like to sweep out these kind of old bugs :) |
This would also end up impacting NaN comparisons. |
It's yours if you want it :) @mazong1123 |
@tannergooding How many special cases of value types can fall into this category? I mean those have different bit representation but considered as the "same" (e.g, +0.0 and - 0.0). I'm asking because I see we already specialized NaN in public override bool Equals(Object obj)
{
if (!(obj is Double))
{
return false;
}
double temp = ((Double)obj).m_value;
// This code below is written this way for performance reasons i.e the != and == check is intentional.
if (temp == m_value)
{
return true;
}
return IsNaN(temp) && IsNaN(m_value);
} We may need to add some methods like |
I found I don't know how the Also here is a related issue #6307 . |
@mazong1123, for Single/Double It should just be -0.0/0.0 and all representations of NaN. However, I am also not familiar with the checks that |
I found
I think who defined the structs should be responsible for handling its own special cases - Like |
@mazong1123, yes, I would, however, continue just comparing |
So the code today is broken for: struct MyStruct
{
public double value1;
public double value2;
} and presumably also for:
Both of these, should be fixed by special handling double. I was calling out a scenario such as the following: struct MyStruct1
{
public double value1;
public MyStruct2 value2;
}
struct MyStruct2
{
public double value;
public override bool Equals(object obj)
{
// custom equality
}
} I am hoping that a bit comparison is not done for this scenario, but I don't know enough about the checks being done to know that for certain (it would probably depend on what triggers |
Other than `ContainsPointers` and `IsNotTightlyPacked`, added two new conditions for checking whether a valuetype can go to fast path or not. Following are the details of these 2 conditions: - Check whether a valuetype contains a Single/Double field. If it does, we cannot go to fast path. Floating point numbers have special `Equals` and `GetHashCode` implementation. We cannot simply compare floating point numbers via bits (e.g. +0.0 should equal to -0.0, but their underlying bits are different). - Check whether an user-defined valuetype overrides `Equals` or `GetHashCode`. If it does, we cannot go to fast path. Because `Equals` or `GetHashCode` result may be different to bit comparison. To find Single/Double fields and overridden `Equals`/`GetHashCode`, we start a DFS to go through the whole hierachy of the source valuetype, and cache the result to `MethodTable`. Fix #11452
coreclr/src/vm/comutilnative.cpp
You can see more information here:
https://blogs.msdn.microsoft.com/xiangfan/2008/09/01/magic-behind-valuetype-equals/
http://stackoverflow.com/questions/2508945/can-anyone-explain-this-strange-behavior-with-signed-floats-in-c/2509152
The text was updated successfully, but these errors were encountered: