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
I would simply use double.IsNaN and let the compiler implicitly cast float members where required:
float myFloat = float.NaN; // or 0.0f / 0.0f;
double myDouble = double.NaN; // or 0.0 / 0.0;
Console.WriteLine(double.IsNaN(myFloat));
Console.WriteLine(double.IsNaN(myDouble));
"Wastes" a very small amount of memory on the stack and uses a cast op call, but hey ho it is generic enough to cater for any type that can hold a "numeric" NaN.
Alternatively, using float.IsNaN appears to work with rudimentary testing, but requires an explicit downcast of a double (downcasting double.NaN and 0.0 / 0.0 appears to work, as in, it reports NaN correctly).
You cannot generically constrain on a subset of value types with any cleanliness (or at all, I'm not 100% certain) so I wouldn't bother chasing the <T> route personally.
static bool IsNaN(dynamic d)
{
float dub;
try
{
dub = (float)d;
return float.IsNaN(dub);
}
catch (RuntimeBinderException)
{
}
return false;
}
However, this incurs boxing. Note as well that dynamic is required and object will not work, so this also invokes the DLR (and also swallows all RuntimeBinderExceptions).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With