Signaling NaN Material for Rationale
August 4, 2000
The following was adopted from NCEG 91-028 (Floating-Point C
Extensions), the last NCEG document to discuss support for Signaling
NaNs. The following should be added to the Rationale as a new annex.
Support for Signaling NaNs
IEC-60559 (International version of IEEE-754) requires two kinds of
NaNs: Quiet NaNs and Signaling NaNs. Standard C only adopted Quiet
NaNs. It did not adopt Signaling NaNs because it was believed that they
are of too limited utility for the amount of work required. But, for
implementations that do wish to support Signaling NaNs, it is highly
recommended that they be supported in the following manner (to promote
consistency in implementations and portability among applications).
184.108.40.206.2 Characteristics of floating types <float.h>
Floating types may support not only numeric values, finite and possibly
infinite, but also NaN (Not-a-Number) values, which do not represent
numbers. A NaN that generally raises an exception when encountered as
an operand of arithmetic operations, is called a signaling NaN; the
operation is said to trigger the signaling NaN. A NaN that behaves
predictably and does not raise exceptions in arithmetic operations is
called a quiet NaN. The IEEE floating-point standards specify quiet and
signaling NaNs, but this document applies the general terms for non-IEEE
implementations as well-for example, the VAX reserved operand and the
CDC and CRAY indefinite qualify as signaling NaNs. In IEEE standard
arithmetic, operations that trigger a signaling NaN argument generally
return a quiet NaN result provided no trap is taken.
The primary utility of quiet NaNs-"to handle otherwise intractable
situations, such as providing a default value for 0.0/0.0" -can be well
supported through straightforward extensions to C.
Other applications of NaNs may prove useful. Available parts of NaNs
have been used to encode auxiliary information, for example about the
NaN's origin. Signaling NaNs are good candidates for filling
uninitialized storage; and their available parts could distinguish
uninitialized floating objects. IEEE signaling NaNs and trap handlers
potentially provide hooks for maintaining diagnostic information or for
implementing special arithmetics.
However, C support for signaling NaNs, or for auxiliary information that
could be encoded in NaNs, is problematic. Implementation mechanisms may
trigger signaling NaNs, or fail to, in mysterious ways. The IEEE
floating-point standards require that NaNs propagate, but not all
implementations faithfully propagate the entire contents. And even the
IEEE standards fail to specify the contents of NaNs through format
conversion, which is pervasive in some C implementation mechanisms.
Whether an operation that merely returns the value of a numeric operand,
changing at most its sign, triggers signaling NaNs is unspecified. Such
operations include conversions that do not change precision, the unary +
and - operators, and the fabs and copysign functions.
Leaving the semantics unspecified allows more efficient implementation.
The IEEE floating-point standards explicitly give the option to
implement same-precision conversions by either arithmetic operations or
data moves, which is important because of the frequency of such
conversions in parameter passing and assignments.
7.12 Mathematics <math.h>
The number classification macros are augmented with
which expands to an integer constant expression with value distinct from
all the other number classification macros. FP_NANS is used to classify
Signaling NaNs. FP_NAN is used to classify Quiet NaNs.
Results for the inquiry macros specified in the remainder of this
section should not trigger signaling NaNs.
7.12.11.x The nans functions
double nans(const char *tagp);
float nansf(const char *tagp);
long double nansl(const char *tagp);
An implementation declares a nans function if and only if it supports
signaling NaNs in the type of the function. The call
nans("n-char-sequence") is equivalent to strtod("NANS(n-char-sequence)",
(char**) NULL). Similarly nansf and nansl are defined in terms of
strtof and strtold. If tagp does not point to an n-char-sequence string
then the result NaN's content is indeterminate.
The nans functions return a signaling NaN with content indicated through
tagp, provided they don't trigger it first.
220.127.116.11 The fprintf function
For a signaling NaN value, the implementation has the options to trigger
the signaling NaN or to converted in one of the styles [-]nans or
[-]nans(n-char- sequence)-which style, and the interpretation of any
n-char-sequence, is implementation-defined.
Use of an upper case format specifier, E, F, or G, results in INF,
INFINITY, NAN, or NANS instead of inf, infinity, nan, or nans.
18.104.22.168 The fscanf function
All valid syntax-including infinity, NaN, and signed zero-is treated in
the same manner as strtod.
The fscanf function should not trigger a signaling NaN that it produces
in response to a signaling NaN input string.
By not triggering signaling NaNs, fscanf provides a way of setting
signaling NaN values. This might appear to be in conflict with the IEEE
floating-point standards which require that binary-decimal conversion
trigger signaling NaN input; however, the conversion of NANS input need
not be regarded as decimal-to-binary conversion.
22.214.171.124 The strtod, strtof, and strtold functions
The syntax accepted by strtod is augmented to include:
Strings of the form NANS or NANS(n-char-sequence-opt) produce signaling
NaNs, if supported, else are treated as invalid input. If a signaling
NaN is produced the implementation has the option of returning it or
triggering it. An implementation may use the n-char-sequence to
determine extra information to be represented in the NaN's significand;
which n-char-sequence's are meaningful is implementation-defined.
The option to trigger a signaling NaN is needed by implementations whose
function-return mechanism involves conversion between different formats,
which may trigger the signaling NaN. For example, an implementation
that returns functions' results in a wider-than-float register might not
be able to return a signaling NaN result for strtof.
Although SNAN would have been a more suggestive representation for
signaling NaNs, NANS was chosen instead because it lessens the
likelihood of consuming non-numeric input, and because IEEE standard 854
says that string representations of NaNs should begin with "NAN". For
quiet NaNs, NAN was chosen over NANQ for brevity and because the
predominance of NaNs in I/O are expected to be quiet.
In addition, the wide character version of the I/O functions should be
argmented to support Signaling NaNs in the same manner as the narrow
character I/O functions.