Shortest way of checking if Double is "NaN"
C#.NetFloating PointC# Problem Overview
When calling Double.IsNaN()
with Double.PositiveInfinity
as argument, the result is false. This is against my intuition since infinity is not a number. Apparently "NaN" only exists in terms of a constant in .NET, is this described by the IEEE standard or is it a custom implementation detail? Is there a shorter way to check if a Double
is "NaN" than:
(Double.IsNaN(d) || Double.IsPositiveInfinity(d) || Double.IsNegativeInfinity(d))
or
(Double.IsNaN(d) || Double.IsInfinity(d))
C# Solutions
Solution 1 - C#
As MSDN says, NaN means that result is undefined. With infinities result is defined:
> A method or operator returns NaN when the result of an operation is > undefined. For example, the result of dividing zero by zero is NaN, as > the following example shows. (But note that dividing a non-zero number > by zero returns either PositiveInfinity or NegativeInfinity, depending > on the sign of the divisor.)
So, it's not good idea to tread infinities as NaN. You can write extension method to check if value is not NaN or infinity:
// Or IsNanOrInfinity
public static bool HasValue(this double value)
{
return !Double.IsNaN(value) && !Double.IsInfinity(value);
}
Solution 2 - C#
You no longer need an extension from SergeyBerezovskiy answer.
double
has IsFinite()
method to check if a double is a finite number (is not NaN
or Infinity
):
double.IsFinite(d)
See source code in .Net Framework and .Net Core
Solution 3 - C#
There are three special values in the Double
type, which is based on IEEE standard 754. One is Positive Infinity, another is Negative Infinity, and the last is Not-a-Number (NaN). All that the Double.IsNaN
method does is check to see if the value in the variable is this special NaN value.
Solution 4 - C#
If you'd like the value of double
to always be a number, you could use this FiniteOrDefault
extension. It is of course inspired by Sergey Berezovskiy's answer.
public static bool HasValue(this double value)
{
return !double.IsNaN(value) && !double.IsInfinity(value);
}
/// <summary>
/// Returns zero when double is NaN or Infinte
/// </summary>
public static double FiniteOrDefault(this double value)
{
return value.HasValue() ? value : default;
}
With that, code like the following can be much more readable:
Rect dimensions = new Rect
{
X = Canvas.GetLeft(Control).FiniteOrDefault(),
Y = Canvas.GetTop(Control).FiniteOrDefault(),
Width = Control.ActualWidth.FiniteOrDefault(),
Height = Control.ActualHeight.FiniteOrDefault()
};