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 RuntimeBinderException
s).
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