2

In .Net the type Double has a static method IsNan() which accepts one parameter, a double and returns a bool.

Surely, this means that the method will always return true as it can only accept a double? Can someone explain the point of this method and when it might return false? Purely curious and wanting to be educated.

Edit: My apologies for a very poorly asked question. You are all right, I should have read the documentation. And, yes I did mean "the method will always return false".

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Digbyswift
  • 10,310
  • 4
  • 38
  • 66

7 Answers7

13

double and float have "Not A Number" values that they use to represent error quantities. A NaN has the unfortunate property that it always compares false to everything, including itself. Thus you call a special method to tell you if a given double is a NaN. (Since NaNs are the only values that have the property that they do not equal themselves, you can also tell if a value is a NaN by comparing it to itself! But x != x looks weird in the code; it is much more idiomatic to simply call IsNaN(x).)

Is there something about the documentation that was so unclear that it prompted you to ask a question here? If you can explain what you found unclear I can pass that feedback on to the documentation manager.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • It is not unfortunate. Several bit patterns indicate a NaN, hence some NaN's may be different from other NaN's. In term of value equality. If IEEE only defined a single bit pattern for NaN, then it would work. – leppie Nov 01 '11 at 13:31
  • 3
    @leppie: It is unfortunate for many reasons, including the fact that it makes the `<` relation on doubles into one that can cause crashes or infinite loops when used in common sort algorithms. One has the reasonable expectation that `<` produces a total order, which it does not. – Eric Lippert Nov 01 '11 at 13:33
  • A bit off topic, but why does .NET not support negative zero floating point values? – leppie Nov 01 '11 at 13:34
  • Thanks for the previous answer, have not thought about it *that* way :) – leppie Nov 01 '11 at 13:36
  • 2
    @leppie: I cannot answer the question because it is based on a false premise. What makes you think .NET doesn't allow representation of negative zero? .NET uses IEEE floats; if you make a negative zero, it'll be treated as an IEEE negative zero. – Eric Lippert Nov 01 '11 at 13:37
  • @leppie: See my answer [here](http://stackoverflow.com/questions/1043816/how-to-get-a-0-result-in-floating-point-calculations-and-distinguish-it-from-0/1043909#1043909) for a demonstration. – Brian Nov 01 '11 at 13:52
  • 1
    also it makes the double.Equals behaviour disagree with == operator. see http://stackoverflow.com/questions/4933769/c-sharp-nan-comparison-differences-between-equals-and – ShuggyCoUk Nov 01 '11 at 15:00
  • @EricLippert: I stand corrected! – leppie Nov 01 '11 at 15:12
  • Or you could use a test of the form `x != x`, like `IsNaN` does itself – harold Nov 05 '11 at 14:12
  • @ShuggyCoUk: Why should `Equals` and `==` be expected to agree? Because of type coercion issues, there will be many unavoidable cases where they disagree. I would suggest that having `Equals` implement test for equivalence would be more helpful than having it test for numerical value equality (that would be especially true, btw, with `Decimal`). – supercat Dec 13 '12 at 00:12
  • @supercat Having two different concepts of equality with differing semantics (in fact given IEquatable *three* different concepts) is a sure fire way to get bugs. Also it actually *doesn't conform to the spec! take the bit batterns 0x7ff0000000000000L + {1,2}, note they are both considered NaN. However try doing a .Equals on them! – ShuggyCoUk Dec 13 '12 at 14:52
  • @leppie "If IEEE only defined a single bit pattern for NaN, then it would work." -- No, it wouldn't ... even the exact same NaN bit pattern is not equal to itself; comparisons to any NaN *always* return false. While there are some valid *mathematical* reasons for this, it is certainly has some unfortunate consequences. – Jim Balter Jun 12 '13 at 20:09
6

No, it will only return true if the value is a "not a number" value (e.g. due to a division by zero). From the docs:

Returns a value indicating whether the specified number evaluates to a value that is not a number (NaN).

and

Floating-point operations return NaN to signal that that result of the operation is undefined. For example, dividing 0.0 by 0.0 results in NaN.

Note that you can't just do:

if (x == double.NaN)

as that comparison will always return false. That's why there's a special method to determine "NaN-ness". (As noted in comments, you could actually detect it by using x != x, which will only be true for "not a number" values - but that's not as clear as using a dedicated method.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Well, you don't *really* need a special method. You could just use `x != x` to determine Nan-ness. The actual implementation is done this way ("CS1718: comparison to same variable" is disabled for this call). – Brian Nov 01 '11 at 14:01
  • @Brian: True. It's a bit nasty though. I'll edit with that information. – Jon Skeet Nov 01 '11 at 14:04
1

Return true if double passed evaluates to NaN; otherwise, false.

aleroot
  • 71,077
  • 30
  • 176
  • 213
0

The NaN (Not a Number) value is defined in here. This function basically checks given double number if it equals to NaN value returns true if that's the case. This can be needed during a debugging or making sure that an arithmetic operation works the way you want and does not return any ambiguous results.

0

Just like doubles have consts representing MinValue and MaxValue, they also have a const representing NaN. One example of when a double operation will return NaN is when diving 0 by 0.

Floating-point operations return NaN to signal that that result of the operation is undefined. For example, dividing 0.0 by 0.0 results in NaN.

Adam
  • 1,172
  • 1
  • 8
  • 12
0

It seems like you are interpreting the method to mean IsNotADouble. But the function isn't that. The method is IsNan, meaning, IsNotANumber. This can happen when the dividing by 0, when some uninitialized memory garbage is rendered as a double, or some other cases. You can read more on Not a Number (NAN) on wikipedia here.

C.J.
  • 15,637
  • 9
  • 61
  • 77
  • Positive and negative infinity are special values which are not NaN and need to be distinguished from that. AFAIK all operators with NaN result in NaN while this is not true for infinity. – Holger Just Nov 01 '11 at 13:35
  • Thanks for clarifying that. I thought they were a special case of NAN. I'll modify my answer. – C.J. Nov 01 '11 at 13:44
0

Double represents a floating point number in C#. These numbers represent fractional numbers but because of the limited bitwidth of the available storage, it can't represent all numbers.

Thus, the standard specifies a special value (actually a couple of those) which are called "not a number" or NaN for short. These special values are different from all other values and are handles specially.

See the Wikipedia entry of NaN for more information.

Note there are other special values like positive and negative infinity, which are distinct from NaN.

Holger Just
  • 52,918
  • 14
  • 115
  • 123