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 ifx
is aNaN
.The expression
x = x
is false ifX
is aNan
.
F.3 Operators and functions
The
isnan
macro in<math.h>
provides theisnan
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
Opencv Image Loading for Opengl Texture
Why Don't I Need to Specify "Typename" Before a Dependent Type in C++20
Why Does Visual Studio Not Perform Return Value Optimization (Rvo) in This Case
Proper Way of Casting Pointer Types
Are All Temporaries Rvalues in C++
Generate Random Numbers in C++ at Compile Time
Avoid Warning 'Unreferenced Formal Parameter'
What Is the Type Signature of a C++11/1Y Lambda Function
Properties File Library for C (Or C++)
Does an Unused Member Variable Take Up Memory
How to Store a Lambda Expression as a Field of a Class in C++11
C++ Performance of Accessing Member Variables Versus Local Variables
Understanding the Different Clocks of Clock_Gettime()