| Home | Libraries | People | FAQ | More

### Introduction

###### The Problem

The C++98 standard does not specify how infinity and NaN are represented in text streams. As a result, different platforms use different string representations. This can cause undefined behavior when text files are moved between different platforms. Some platforms cannot even input parse their own output! So 'route-tripping' or loopback of output to input is not possible. For instance, the following test fails with MSVC:

    stringstream ss;
    double inf = numeric_limits<double>::infinity();
    double r;
    ss << inf; // Write out.
    ss >> r; // Read back in.

    cout << "infinity output was " << inf << endl; // 1.#INF
    cout << "infinity input was " << r << endl; // 1

    assert(inf == y); // Fails!

###### The Solution

The facets `nonfinite_num_put` and `nonfinite_num_get` format and parse all floating-point numbers, including `infinity` and `NaN`, in a consistent and portable manner.

The following test succeeds with MSVC.

    locale old_locale;
    locale tmp_locale(old_locale, new nonfinite_num_put<char>);
    locale new_locale(tmp_locale, new nonfinite_num_get<char>);

| Tip
To add two facets, `nonfinite_num_put` and `nonfinite_num_get`, you may have to add one at a time, using a temporary locale. Or you can create a new locale in one step `std::locale new_locale(std::locale(std::locale(std::locale(), new boost::math::nonfinite_num_put<char>), new boost::math::nonfinite_num_get<char>));` and, for example, use it to imbue an input and output stringstream.

| Tip
To just change an input or output stream, you can concisely write `cout.imbue (std::locale(std::locale(), new boost::math::nonfinite_num_put<char>));` or `cin.imbue (std::locale(std::locale(), new boost::math::nonfinite_num_get<char>));`

    stringstream ss;
    ss.imbue(new_locale);
    double inf = numeric_limits<double>::infinity();
    ss << inf; // Write out.
    BOOST_MATH_ASSERT(ss.str() == "inf");
    double r;
    ss >> r; // Read back in.
    BOOST_MATH_ASSERT(inf == r); // Confirms that the double values really are identical.

    cout << "infinity output was " << ss.str() << endl;
    cout << "infinity input was " << r << endl;
    // But the string representation of r displayed will be the native type
    // because, when it was constructed, cout had NOT been imbued
    // with the new locale containing the nonfinite_numput facet.
    // So the cout output will be "1.#INF on MS platforms
    // and may be "inf" or other string representation on other platforms.

##### C++0X standard for output of infinity and NaN

C++0X (final) draft standard does not explicitly specify the representation (and input) of nonfinite values, leaving it implementation-defined. So without some specific action, input and output of nonfinite values is not portable.

##### C99 standard for output of infinity and NaN

The C99 standard does specify how infinity and NaN are formatted by printf and similar output functions, and parsed by scanf and similar input functions.

The following string representations are used:

Table 2.1. C99 Representation of Infinity and NaN

number | string
--- | ---
Positive infinity | "inf" or "infinity"
Positive NaN | "nan" or "nan(...)"
Negative infinity | "-inf" or "-infinity"
Negative NaN | "-nan" or "-nan(...)"

So following C99 provides a sensible 'standard' way of handling input and output of nonfinites in C++, and this implementation follows most of these formats.

###### Signaling NaNs

A particular type of NaN is the signaling NaN. The usual mechanism of signaling is by raising a floating-point exception. Signaling NaNs are defined by IEEE 754-2008.

Floating-point values with layout s111 1111 1axx xxxx xxxx xxxx xxxx xxxx where s is the sign, x is the payload, and bit a determines the type of NaN.

If bit a = 1, it is a quiet NaN.

If bit a is zero and the payload x is nonzero, then it is a signaling NaN.

Although there has been theoretical interest in the ability of a signaling NaN to raise an exception, for example to prevent use of an uninitialised variable, in practice there appears to be no useful application of signaling NaNs for most current processors. C++0X 18.3.2.2 still specifies a (implementation-defined) representation for signaling NaN, and `static constexpr bool has_signaling_NaN` a method of checking if a floating-point type has a representation for signaling NaN.

But in practice, most platforms treat signaling NaNs in the same as quiet NaNs. So, for example, they are represented by "nan" on output in C99 format, and output as `1.#QNAN` by Microsoft compilers.

| Note
The C99 standard does not distinguish between the quiet NaN and signaling NaN values. A quiet NaN propagates through almost every arithmetic operation without raising a floating-point exception; a signaling NaN generally raises a floating-point exception when occurring as an arithmetic operand. C99 specification does not define the behavior of signaling NaNs. NaNs created by IEC 60559 operations are always quiet. Therefore this implementation follows C99, and treats the signaling NaN bit as just a part of the NaN payload field. So this implementation does not distinguish between the two classes of NaN.

| Note
An implementation may give zero and non-numeric values (such as infinities and NaNs) a sign or may leave them unsigned. Wherever such values are unsigned, any requirement in the C99 Standard to retrieve the sign shall produce an unspecified sign, and any requirement to set the sign shall be ignored. This might apply to user-defined types, but in practice built-in floating-point types `float`, `double` and `long double` have well-behaved signs.

The numbers can be of type `float`, `double` and `long double`. An optional + sign can be used with positive numbers (controlled by ios manipulator `showpos`). The function `printf` and similar C++ functions use standard formatting flags to put all lower or all upper case (controlled by `std::ios` manipulator `uppercase` and `lowercase`).

The function `scanf` and similar input functions are case-insensitive.

The dots in `nan(...)` stand for an arbitrary string. The meaning of that string is implementation dependent. It can be used to convey extra information about the NaN, from the 'payload'. A particular value of the payload might be used to indicate a missing value, for example.

This library uses the string representations specified by the C99 standard.

An example of an implementation that optionally includes the NaN payload information is at AIX NaN fprintf. That implementation specifies for Binary Floating Point NANs:

- A NaN ordinal sequence is a left-parenthesis character '(', followed by a digit sequence representing an integer n, where 1 <= n <= INT_MAX-1, followed by a right-parenthesis character ')'.
- The integer value, n, is determined by the fraction bits of the NaN argument value as follows:
- For a signalling NaN value, NaN fraction bits are reversed (left to right) to produce bits (right to left) of an even integer value, 2*n. Then formatted output functions produce a (signalling) NaN ordinal sequence corresponding to the integer value n.
- For a quiet NaN value, NaN fraction bits are reversed (left to right) to produce bits (right to left) of an odd integer value, 2*n-1. Then formatted output functions produce a (quiet) NaN ordinal sequence corresponding to the integer value n.

| Warning
This implementation does not (yet) provide output of, or access to, the NaN payload.