### 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.