Nullable double NaN comparison in C#
Asked Answered
E

5

7

I have 2 nullable doubles, an expected value and an actual value (let's call them value and valueExpected). A percentage is found using 100 * (value / valueExpected). However, if valueExpected is zero, it returns NaN. Everything good so far.

Now, what do I do if I need to check the value, to see if it is NaN? Normally one could use:

if (!Double.IsNaN(myDouble))

But this doesn't work with nullable values (IsNaN only works with non-nullable variables). I have changed my code to do the check (valueExpected == 0), but I'm still curious - is there any way to check for a nullable NaN?

Edit: When I say the code doesn't work, I mean it won't compile. Testing for null first doesn't work.

Equalitarian answered 28/11, 2012 at 3:25 Comment(0)
L
10

With all Nullable<T> instances, you first check the bool HasValue property, and then you can access the T Value property.

double? d = 0.0;        // Shorthand for Nullable<double>
if (d.HasValue && !Double.IsNaN(d.Value)) {
    double val = d.Value;

    // val is a non-null, non-NaN double.
}
Leonardoleoncavallo answered 28/11, 2012 at 3:29 Comment(7)
Perhaps it is just visual studio that is preventing me. I did have something like: ` if(myDouble != null) { if (!Double.IsNaN(myDouble)) { //Do stuff! } } ` But this and your code doesn't compile, it still doesn't like using IsNaN, even after the 'is null' check.Equalitarian
Did you see the ".Value" after the variable name "d". d.Value is a double and it should definitely compile.Syst
My code compiles just fine. The "is null" check you added doesn't change anything. Your code is still incorrect. myDouble is a Nullable<double> while IsNaN() expects a double. You must use the .Value property.Leonardoleoncavallo
Ah! Yep, that works. So the .value will use it as a non-nullable type. Thanks! I missed the .value.Equalitarian
Did you happen to check out the documentation? MSDN is your best friend when it comes to these things. .Value actually returns the actual underlying value. Nullable<T> is really just a T and a bool under the hood.Leonardoleoncavallo
I've never actually used the Nullable<double> notation, I've always used the double? way, which made it difficult to search. But I'll keep that in mind.Equalitarian
Glad I could help. Remember to upvote any answer that helped, and accept the one that best answers your question.Leonardoleoncavallo
B
4

You can also use

if (!Double.IsNaN(myDouble ?? 0.0))

The value in the inner-most parenthesis is either the myDouble (with its Nullable<> wrapping removed) if that is non-null, or just 0.0 if myDouble is null. Se ?? Operator (C#).

Bain answered 11/12, 2012 at 22:32 Comment(0)
S
0

I had the same issue and I solved it with casting the double? with double

double.IsNaN((double)myDouble)

this will return true if NaN and false if not

Suu answered 25/3, 2015 at 3:45 Comment(1)
Note that this will not work (throw an exception System.InvalidOperationException: Nullable object must have a value.) whenever myDouble == null which is the point of having a nullable...Bostick
U
0

With C# 7.0 Pattern matching combined null + NaN check check can be written like this:

double? d = whatever;
if(d is double val && double.IsNaN(val))
   Console.WriteLine(val);

The advantage is local scoped variable val at hand, which is not null, nor double.NaN and can even be used outside of if.

Undercroft answered 18/11, 2020 at 13:40 Comment(0)
B
0

With pattern matching in newer Roslyn C# versions, double.NaN is a valid pattern which tests using IsNaN (that is it works differently than Equals() where NaN is never equal to NaN as specified by IEEE floating point standard).

Therefore you can now do this:

double? myDouble = something;
if (myDouble is double and not double.NaN)
   Console.WriteLine("A number");

For testing NaN this can even be shortened like this:

double? myDouble = something;
if (myDouble is double.NaN)
   Console.WriteLine("Not a number and not NULL");
Bostick answered 13/10, 2021 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.