Infinity and NaN Support

IBM C and C++ Compilers supports the use of infinity and NaN (not-a-number) values. Infinity is a value with an associated sign that is mathematically greater in magnitude than any binary floating-point number. A NaN is a value in floating-point computations that is not interpreted as a mathematical value, and that contains a mask state and a sequence of binary digits.

The value of infinity can be computed from 1.0 / 0.0. The value of a NaN can be computed from 0.0 / 0.0.

Depending on its bit pattern, a NaN can be either quiet (NaNQ) or signalling (NaNS). A NaNQ is masked and never generates exceptions. A NaNS may be masked and may generate an exception, but does not necessarily do so. IBM C and C++ Compilers supports only quiet NaN values; all NaN values discussed below refer to quiet NaNs.

NaN and infinity values are defined as macro constants in the <float.h> header file. The macros are:

Macro Description
_INFINITYF Infinity of type float.
_INFINITY Infinity of type double.
_INFINITYL Infinity of type long double.
_INFF Same as _INFINITYF.
_INF Same as _INFINITY.
_INFL Same as _INFINITYL.
_NANF Quiet NaN of type float.
_NAN Quiet NaN of type double.
_NANL Quiet NaN of type long double.

You can get the corresponding negative values by using the unary minus operator (for example, -_INF).

Note: The value of 0.0 can also be positive or negative. For example, 1.0 / (-0.0) results in -_INF.

Because these macros are actually references to constant variables, you cannot use them to initialize static variables. For example, the following statements are not allowed:

static double infval = _INF;
static float nanval = 1.0 + _NANF;

However, you can initialize static variables to the numeric values of infinity and NaN:

static double infval = 1.0 / 0.0;
static float nanval = 0.0 / 0.0;

Note: Although positive and negative infinities are specific bit patterns, NaNs are not. A NaN value is not equal to itself or to any other value. For example, if you assign a NaN value to a variable x, you cannot check the value of x with the statement if (_NAN == x). Instead, use the statement if (x != x).

All relational and equality expressions involving NaN values always evaluate to FALSE or zero (0), with the exception of not equal (!=), which always evaluates to TRUE or one (1).

Infinity and NaN in Library Functions
When you set the language level to extended (using the lang(level, extended) option or the #pragma langlvl(extended) directive), which is the default, infinity and NaN values can be passed as arguments to the scanf and printf families of library functions, and to the string conversion and math functions.

This section describes how the library functions handle the infinity and NaN values.

scanf Family:

The scanf family of functions includes the functions scanf, fscanf, fwscanf, sscanf, wscanf and swscanf. When reading in floating-point numbers, these functions convert the strings INFINITY, INF, and NAN (in upper-, lower-, or mixed case) to the corresponding floating-point value. The sign of the value is determined by the format specification.

Given a string that consists of NAN, INF, or INFINITY, followed by other characters, the scanf functions read in only the NaN or infinity value, and consider the rest of the string to be a second input field. For example, Nancy would be scanned as two fields, Nan and cy.

Note: In the case of a string that begins with INF, the functions check the fourth letter. If that letter is not I (in upper- or lowercase), INF is read and converted and the rest of the string is left for the next format specifications. If the fourth letter is I, the functions continue to scan for the full INFINITY string. If the string is other than INFINITY, the entire string is discarded.

Example
In this example, fscanf converts NaN and infinity strings to their numeric values.

#include <stdio.h>
int main(void)
{
   int n, count;
   double d1, d2, d3;
   FILE *stream;
   stream = tmpfile();
   fputs(" INFINITY NAn INF", stream);
   rewind(stream);
   n = fscanf(stream, "%lF%lf%lF%n", &d1, &d2, &d3, &count);
   if (n != EOF)
   {
      printf("Number of fields converted = %d\n", n);
      printf("Number of characters read = %d\n", count);
      printf("Output = %f %F %F\n", d1, d2, d3);
   }
   return 0;
   /******************************************************
      The expected output is:
      Number of fields converted = 3
      Number of characters read = 17
      Output = infinity NAN INFINITY
   ******************************************************/
}

printf Family:

The printf family of functions includes the functions printf, fprintf, fwprintf, sprintf, swprintf, vfprintf, vfwprintf, vprintf, vsprintf, vswprintf, and wprintf. These functions convert floating-point values of infinity and NaN to the strings "INFINITY" or "infinity" and "NAN" or "nan".

The case is determined by the format specification, as is the sign (positive or negative). When converting these values, the printf functions ignore the precision width given by the format specification.

Example
In this example, printf converts the NaN and infinity values, and prints out the corresponding string.

#include <stdio.h>
#include <float.h>
int main(void)
{
   double infval = -(_INF);
   float nanval = _NANF;
   printf("-_INF is the same as %-15.30f\n", infval);
   printf("_NANF is the same as %-15.30F\n", nanval);
   return 0;
   /***************************************************
      The expected output is:
      -_INF is the same as -infinity
      _NANF is the same as NAN
   ****************************************************/
}

String Conversion Functions:

The string conversion functions that support infinity and NaN representations include the functions atof, _atold, _ecvt, _fcvt, _gcvt, strtod, strtold, and wcstod.

The atof, _atold, strtod, strtold, and wcstod functions accept the strings INFINITY, INF, and NAN (in upper-, lower-, or mixed case) as input, and convert these strings to the corresponding macro value defined in <float.h>. The _ecvt, _fcvt, and _gcvt functions convert infinity and NaN values to the strings INFINITY and NAN, respectively.

Note: If a signalling NaN string is passed to a string conversion function, a quiet NaN value is returned, and no signal is raised.

Example
The following example uses atof to convert the strings "naN" and "inf" to the corresponding macro value.

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
   char *nanstr;
   char *infstr;
   nanstr = "naN";
   printf( "Result of atof = %.10e\n", atof(nanstr) );
   infstr = "inf";
   printf( "Result of atof = %.10E\n", atof(infstr) );
   return 0;
   /**************************************************
      The expected output is:
      Result of atof = nan
      Result of atof = INFINITY
   **************************************************/
}

Math Functions:

Most math functions accept infinity, negative infinity, and NaN values as input. (For information on those functions that do not accept these values, see "Math Functions without Infinity and NaN Support" below.) In general, a NaN value as input results in a NaN value as output, and infinity values as input usually result in infinity values. If the input value is outside the domain or range of the function, errno is set to EDOM or ERANGE, respectively.

The following tables display the results of each math function when NaN or infinity values are input, and the associated errno value if one exists. The first table lists the functions that take only one argument; the second lists those that take two arguments.

Note: In some cases, infinity is always a valid input value for the function, regardless of the language level (for example, atan). These cases do not appear in these two tables.

Function Input Result errno Value
acos
asin
NaN
infinity
-infinity
NaN
0
0

EDOM
EDOM
atan NaN NaN  
ceil
floor
NaN
infinity
-infinity
NaN
infinity
-infinity
 
cos
tan
NaN
infinity
-infinity
NaN
NaN
NaN
EDOM
ERANGE
ERANGE
cosh NaN
infinity
-infinity
NaN
infinity
infinity

ERANGE
ERANGE
erf NaN
infinity
-infinity
NaN
1
-1
EDOM

erfc NaN
infinity
-infinity
NaN
0
2
EDOM

exp NaN
infinity
-infinity
NaN
infinity
0

ERANGE
ERANGE
fabs NaN
infinity
-infinity
NaN
infinity
infinity
 
frexp NaN
infinity
-infinity
NaN, 0
NaN, 0
NaN, 0
EDOM
EDOM
EDOM
gamma NaN
infinity
-infinity
NaN
infinity
NaN
EDOM
ERANGE
EDOM
log
log10
NaN
infinity
0
<0
NaN
infinity
-infinity
NaN


ERANGE
EDOM
modf NaN
infinity
-infinity
NaN, NaN
NaN, infinity
NaN, -infinity
EDOM
EDOM
EDOM
sin NaN
infinity
-infinity
NaN
infinity
-infinity
EDOM
ERANGE
ERANGE
sinh NaN
infinity
-infinity
NaN
infinity
-infinity
EDOM
ERANGE
ERANGE
sqrt NaN
infinity
-infinity
NaN
infinity
0


EDOM
tanh NaN
infinity
-infinity
NaN
1
-1
EDOM

The functions in the following table take two arguments. The results from NaN and infinity values vary depending on which argument they are passed as.(1)

Function Argument 1 Argument 2 Result errno Value
atan2 NaN
any number
any number
NaN
NaN
NaN
EDOM
fmod NaN
any number
+/-infinity
any number
NaN
any number
NaN
NaN
0
EDOM
EDOM
EDOM
ldexp infinity
-infinity
NaN
any number
any number
any number
infinity
-infinity
NaN
ERANGE
ERANGE
EDOM
pow NaN
any number
0
0
+/-infinity
infinity
-infinity
infinity
-infinity
1
-1
>1
>1
infinity
infinity
<-1
<-1
-infinity
-infinity
<-1
-infinity
<-1
-infinity
>1
>1
infinity
infinity
>0, <1
>0, <1
<0, >-1
<0, >-1
<0, >-1
<0, >-1
>0, <1
>0, <1
any number
NaN
<0
0
0
1
1
-1
-1
+/-infinity
+/-infinity
>0, !=1
infinity
>0, !=1
infinity
>0, !=1
infinity
>0, !=1
infinity
<0, !=-1
<0, !=-1
-infinity
-infinity
<0, !=-1
-infinity
<0, !=-1
-infinity
>0
infinity
>0
infinity
<0
-infinity
<0
-infinity
NaN
NaN
infinity
NaN
NaN
infinity
-infinity
0
-0
NaN
NaN
infinity
infinity
infinity
infinity
-infinity(2)
NaN
-infinity(2)
NaN
-0.0(3)
-0.0(3)
NaN
NaN
0.0
0.0
0.0
0.0
0
0
-0(3)
NaN
-infinity(2)
NaN
infinity
infinity
EDOM
EDOM
EDOM
EDOM
EDOM
ERANGE
ERANGE
ERANGE
ERANGE
EDOM
EDOM
ERANGE
ERANGE
ERANGE
ERANGE
ERANGE(4)
EDOM
ERANGE(4)
EDOM
ERANGE(4)
ERANGE(4)
EDOM
EDOM
ERANGE
ERANGE
ERANGE
ERANGE
ERANGE
ERANGE
ERANGE(4)
EDOM
ERANGE(4)
EDOM
ERANGE
ERANGE
Notes:
  1. If a signalling NaN is passed to a math function, the behavior is undefined.
  2. If Argument 2 is even, then the result is infinity.
  3. If Argument 2 is even, then the result is 0.0.
  4. If Argument 2 is not an integer, then the result is NaN and errno Value is EDOM.

Math Functions without Infinity and NaN Support:

The following floating-point unit functions are not supported for use with infinity or NaN values. In general, a NaN or infinity value as input for these functions results in an undefined value, an invalid operation exception, or both. These functions do not set errno.

_facos _fasin _fcos _fcossin
_fpatan _fptan _fsin _fsincos
_fsqrt _fyl2x _fyl2xp1 _f2xm1

Note: If you expect the return value of a math function to be infinity or NaN, you should use the functions that are supported for these values. The advantage in using the floating-point unit math functions is a reduction in the processing time and in the size of your executable file.