I need to find min and max values in an array (not taking into for possible NaN values in this array).
This would be easy only working with double
, but these FindMin and FindMax functions have to work with generics types.
I have tried to test for generic NaNs in this way:
bool isNaN<T>(T value) where T : IEquatable<T>
{
return !value.Equals(value);
}
but Equals
is returning true
for double.NaN
??!!
I have a workaround like this for now:
bool isNaN<T>(T value) where T : IEquatable<T>
{
var d = value as double?;
if (d.HasValue) { return double.IsNaN(d.Value); }
return !value.Equals(value);
}
My question is more about understanding why first solution did not work, is this a bug ?
You can find small test code here
but Equals is returning true for double.NaN
Yes. And it does regardless of generics:
double x = double.NaN;
Console.WriteLine(x.Equals(x)); // True
Console.WriteLine(x == x); // False
Note that if the second line printed False, that would either make the IEquatable<T>.Equals
inconsistent with the Equals(object)
override, or you'd have to make Equals(object)
violate the reflexivity requirement of object.Equals(object)
.
Basically this sort of thing is nasty whatever you do with it.
Given that you're trying to find max/min values, you might want to try using IComparable<T>
instead of IEquatable<T>
- that may well let you detect NaN in other ways. (I don't have time to check right now.)