0

My understanding is that NaN (Not a Number) is essentaly a constant that is returned from a mathematical function to indicate something went wrong or the calculation is invalid. So it makes sense that their are functions to check if a number is NaN or better yet, use the CERT Coding Standard to do error checking for mathematical errors ( https://www.securecoding.cert.org/confluence/display/c/FLP32-C.+Prevent+or+detect+domain+and+range+errors+in+math+functions ).

My question is this; why does std::nan() exist? Why would you ever want to take a valid number/string/value and convert it to NaN? (Refrence: http://en.cppreference.com/w/cpp/numeric/math/nan )

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Katianie
  • 589
  • 1
  • 9
  • 38
  • 3
    Completeness with the standard. NaNs can have different values. It might be necessary to create a specific NaN for test code, to compare against. It might even be necessary to _detect_ a specific NaN at runtime. – davidbak Oct 07 '16 at 17:58
  • Does that imply that there are a series of NaN constants that represent specific errors? – Katianie Oct 07 '16 at 17:59
  • I'm not sure, but I doubt that there is a _standard_ set of such NaN constants. But your particular CPU/coprocessor/math library might have documentation to indicate some specific values it may return ... – davidbak Oct 07 '16 at 18:01
  • Note: there is also `std::numeric_limits::quiet_NaN()` –  Oct 07 '16 at 18:03
  • What is a quiet NaN? – Katianie Oct 07 '16 at 18:04
  • 2
    A NaN you can use in a library! Shhhh! – davidbak Oct 07 '16 at 18:04
  • (For a real answer about quiet/signaling NaNs, try http://stackoverflow.com/questions/18118408/what-is-difference-between-quiet-nan-and-signaling-nan) – davidbak Oct 07 '16 at 18:05
  • 1
    @Katianie A signaling NAN may cause an CPU-exception (a quiet not) –  Oct 07 '16 at 18:05
  • 1
    There are no specific errors that correspond to different `NaN` values. From [the spec](http://www.cplusplus.com/reference/cmath/nan-function/): _"The argument can be used by library implementations to distinguish different NaN values in a implementation-specific manner."_ Note that an implementation is not even required to support different `NaN` values. (A _quiet `NaN`_ is a `NaN` that does not raise an exception if it is used in an operation and simply propagates through. See the [WIkipedia article on `NaN`](https://en.wikipedia.org/wiki/NaN) for more info.) – Ted Hopp Oct 07 '16 at 18:06

3 Answers3

2

NaN is often used to indicate a null or missing value, especially in data analyisis and data science. So it is common for an application to initialize values to nan, in order to track whether a value has been provided or not without the overhead of using optional<T>-like structures.

Secondarily, it common to create custom math functions that you want to return nan for certain inputs. So it's more than just for completeness.

Inverse
  • 4,408
  • 2
  • 26
  • 35
  • So you can use NaNs for in-band error signaling? Out of curiosity, do you have any example library whose documentation I can look at that does this? – davidbak Oct 07 '16 at 18:03
  • Numpy and pandas are a good example: http://pandas.pydata.org/pandas-docs/stable/missing_data.html – Inverse Oct 07 '16 at 19:23
  • And to follow on, the reason nans are preferred here is that you can continue calculating as usual with nans (such as in large vector operation) and the nan values will naturally propagate to the final result and only on values that were impacted. – Inverse Oct 07 '16 at 19:25
1

Suppose you want to implement std::acos. How would you return nan in case of invalid input (|arg| < 1)? It should be possible to implement such functions in C++. Beside that fact, that you may need to write a function which is not provided by STL, one of distinctive charts of C++ is that it's standard library can be written on C++.

Alexey Guseynov
  • 5,116
  • 1
  • 19
  • 29
  • This is how I implement acos: if (islessequal(-1, numInRadians) == true && islessequal(numInRadians, 1) == true) { return acos(numInRadians); } return -1.0; – Katianie Oct 07 '16 at 18:03
  • @Katianie Suppose you had no `acos` function to call. – erip Oct 07 '16 at 18:08
  • Good point, If i dident have an acos to call. But since I do in this case, For my other math functions, I check for polling and domain errors the same way the CERT standard does (see link in my question). That way I never actually come into any contact with NaN values. – Katianie Oct 07 '16 at 18:10
  • 2
    @Katianie, one way to check that you're not calling a math function with a value out of its domain is to check in advance, _each time you call a function_, knowing the domain of that fn, as you suggest. Another way (in IEEE arithmetic) is just to call the function and see if it comes back with a NaN. The latter has the advantage that if you use quiet NaNs - which propagate - you can compute an entire expression and at the end determine if, at any time during that computation, you went out of domain. (Or if you use signaling NaNs you'll get an exception thrown when you're out of domain.) – davidbak Oct 07 '16 at 18:18
1

IEEE 754 systematically introduced the use of NaN to represented numbers whose definitions could otherwise not be represented on computers.

You'll often see this for 0/0, ±inf / ±inf, 0 * ±inf, etc.

erip
  • 16,374
  • 11
  • 66
  • 121
  • But are there defined (in the standard) distinct NaNs for those out-of-domain results? – davidbak Oct 07 '16 at 18:10
  • check out this link: https://www.securecoding.cert.org/confluence/display/c/FLP32-C.+Prevent+or+detect+domain+and+range+errors+in+math+functions I followed it on how to check for polling and domain errors. – Katianie Oct 07 '16 at 18:12
  • @davidbak By standard I assume you mean IEEE standard. In 754 there were a few interesting implications regarding NaN. Specifically that the only operation on NaN that is defined to be true are `NaN != NaN`, so no two NaNs are the same. – erip Oct 07 '16 at 18:12