Using Nan in C++

How to use nan and inf in C?

You can test if your implementation has it:

#include <math.h>
#ifdef NAN
/* NAN is supported */
#endif
#ifdef INFINITY
/* INFINITY is supported */
#endif

The existence of INFINITY is guaranteed by C99 (or the latest draft at least), and "expands to a constant expression of type float representing positive or unsigned
infinity, if available; else to a positive constant of type float that overflows at translation time."

NAN may or may not be defined, and "is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN."

Note that if you're comparing floating point values, and do:

a = NAN;

even then,

a == NAN;

is false. One way to check for NaN would be:

#include <math.h>
if (isnan(a)) { ... }

You can also do: a != a to test if a is NaN.

There is also isfinite(), isinf(), isnormal(), and signbit() macros in math.h in C99.

C99 also has nan functions:

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

(Reference: n1256).

Docs INFINITY
Docs NAN

How to produce a NaN float in c?

Using floating point numbers, 0.0 / 0.0 isn't a "divide by zero" error; it results in NaN.

This C program prints -nan:

#include <stdio.h>

int main()
{
float x = 0.0 / 0.0;
printf("%f\n", x);
return 0;
}

In terms what NaN looks like to the computer, two "invalid" numbers are reserved for "signaling" and "quiet" NaN (similar to the two invalid numbers reserved for positive and negative infinity). The Wikipedia entry has more details about how NaN is represented as an IEE floating point number.

How to generate NaN, -Infinity and +Infinity in ANSI C?

There is in C99, but not in previous standards AFAIK.

In C99, you'll have NAN and INFINITY macros.

From "Mathematics <math.h>" (§7.12) section

The macro INFINITY expands to a constant expression of type float representing positive or unsigned infinity, if available; ...

If you're stuck with ANSI C89, you're out of luck. See C-FAQ 14.9.

C/C++ NaN constant (literal)?

In C, NAN is declared in <math.h>.

In C++, std::numeric_limits<double>::quiet_NaN() is declared in <limits>.

But for checking whether a value is NaN, you can't compare it with another NaN value. Instead use isnan() from <math.h> in C, or std::isnan() from <cmath> in C++.

Checking if a double (or float) is NaN in C++

According to the IEEE standard, NaN values have the odd property that comparisons involving them are always false. That is, for a float f, f != f will be true only if f is NaN.

Note that, as some comments below have pointed out, not all compilers respect this when optimizing code.

For any compiler which claims to use IEEE floating point, this trick should work. But I can't guarantee that it will work in practice. Check with your compiler, if in doubt.

Is `x!=x` a portable way to test for NaN?

Please refer to the normative section Annex F: IEC 60559 floating-point arithmetic of the C standard:

F.1 Introduction

An implementation that defines __STDC_IEC_559__ shall conform to the specifications in this annex.

Implementations that do not define __STDC_IEC_559__ are not required to conform to these specifications.

F.9.3 Relational operators

The expression x ≠ x is true if x is a NaN.

The expression x = x is false if X is a Nan.

F.3 Operators and functions

The isnan macro in <math.h> provides the isnan function recommended in the Appendix to IEC 60559.

In what situation do we get nan in c++?

With input of “2”, your program adds two infinities of opposite signs, which generates a NaN. This occurs because repeatedly multiplying pow by two causes it to become infinity, and the alternating sign results in a positive infinity being added to a negative infinity in sum from the previous iteration or vice-versa.

However, it is not clear why you see any output, as counter++ becomes ineffective once counter reaches 253 (in typical C++ implementations) because then the double format lacks precision to represent 253+1, so the result of adding one to 253 is rounded to 253. So counter stops changing, and the loop continues forever.

One possibility is that your compiler is generating code that always terminates the loop, because this is allowed by the “Forward progress” clause (4.7.2 in draft n4659) of the C++ standard. It says the compiler can assume your loop will not continue forever without doing something useful (like writing output or calling exit), and that allows the compiler to generate code that exits the loop even though it would otherwise continue forever with input of “2”.

Per the IEEE-754 standard, operations that produce NaN as a result include:

  • operations on a NaN,
  • multiplication of zero by an infinity,
  • subtraction of two infinities of the same sign or addition of two infinities of opposite signs,
  • division of zero by zero or an infinity by an infinity,
  • remainder when the divisor is zero or the dividend is infinity,
  • square root of a value less than zero,
  • various exceptions in some utility and mathematical routines (such as pow, see IEEE-754 9.2, 5.3.2, and 5.3.3).

C++ implementations do not always conform to IEEE-754, but these are generally good guidelines for sources of NaNs.

Using NaN in C++?

After looking into this some more, it looks like signaling_NaN is useless as provided. If floating point exceptions are enabled, then calling it counts as processing a signaling NaN, so it immediately raises an exception. If floating point exceptions are disabled, then processing a signaling NaN automatically demotes it to a quiet NaN, so signaling_NaN doesn't work either way.

Menkboy's code works, but trying to use signaling NaNs runs into other problems: there's no portable way to enable or disable floating point exceptions (as alluded to here and here), and if you're relying on exceptions being enabled, third party code may disable them (as described here).

So it seems like Motti's solution is really the best choice.

NaN comparison rule in C/C++

C/C++ does not require specific floating-point representation and does not require that any comparison against NaN is false.

In C++ you can check if all floating-point types fulfill IEEE 754 using std::numeric_limits::is_iec559:

static constexpr bool is_iec559;

56 True if and only if the type adheres to IEC 559 standard.217

57 Meaningful for all floating point types.



217) International Electrotechnical Commission standard 559 is the same as IEEE 754.

For other floating-point representations comparison against NaN
may or may not behave the same way.

In fact, even representing NaN itself is not required. See std::numeric_limits<T>::has_quiet_NaN,
std::numeric_limits<T>::has_signaling_NaN.

NaN Literal in C?

In C99's <math.h>

  7.12  Mathematics <math.h>
   [#5] The macro

NAN

is defined if and only if the implementation supports quiet
NaNs for the float type. It expands to a constant
expression of type float representing a quiet NaN. |


Related Topics



Leave a reply



Submit