Reputation: 1015
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))
Upvotes: 68
Views: 75400
Reputation: 612
In the end, all you are looking at is the bit value of the double. The IEEE standard 754, used by double, states:
Therefore, if you don't want to use built-in functions, you can simply check if all Exponent bits are set yourself. You can do this in one of two ways, use unsafe code to extract long value of double or use BitConverter.DoubleToInt64Bits
, then check Exponent bits.
public unsafe static bool IsNaNorInfinity(double d)
{
return (*(long*)(&d) & 0x7FF0000000000000L) == 0x7FF0000000000000L;
}
public static bool IsNaNorInfinity(double d)
{
return (BitConverter.DoubleToInt64Bits(d) & 0x7FF0000000000000L) == 0x7FF0000000000000L;
}
Upvotes: 1
Reputation: 1505
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()
};
Upvotes: 5
Reputation: 24569
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
Upvotes: 20
Reputation: 8594
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.
Upvotes: 4
Reputation: 236208
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);
}
Upvotes: 83