ISO/ IEC JTC1/SC22/WG14 N747

                           Document Number:  WG14 N747/J11 97-110


                               C9X Revision Proposal
                               =====================

       Title: IEC 559 Binding: Signaling NaNs
       Author: Fred J. Tydeman
       Author Affiliation: Tydeman Consulting
       Postal Address: 3711 Del Robles Dr., Austin, Texas, USA, 78727
       E-mail Address: [email protected]
       Telephone Number: +1 (512) 255-8696
       Fax Number: +1 (512) 255-8696
       Sponsor: WG14
       Date: 1997-09-16
       Proposal Category:
          __ Editorial change/non-normative contribution
          Y_ Correction
          Y_ New feature
          __ Addition to obsolescent feature list
          __ Addition to Future Directions
          __ Other (please specify)  ______________________________
       Area of Standard Affected:
          __ Environment
          __ Language
          __ Preprocessor
          Y_ Library
             Y_ Macro/typedef/tag name
             Y_ Function
             __ Header
          __ Other (please specify)  ______________________________
       Prior Art: None known.
       Target Audience: Programmers that need to detect use of
       uninitialized floating-point variables._____________________
       Related Documents (if any): C9X working draft 10; IEC 559
       or IEEE-754; IEEE-854.
       Proposal Attached: _Y Yes __ No, but what's your interest?

       Abstract: IEC 559 (IEEE-754) requires Signaling NaNs.
       Signaling NaNs are missing from the current C9X binding of
       IEC 559.  This adds them so that the C binding of IEC 559
       conforms to all the required parts of IEC 559.  This also is
       a prerequisite to adding LIA-1 to C9X, but only because it
       is a required feature of IEC 559.

       This is being proposed because it is a 'required' feature,
       not because it is a useful feature.

       [ISSUE: What to do with this?
       1) Add as changes to existing body and annexes.  That is how
       this is currently written.
       2) Add as new informative annex.  We need to say in C9X that
       signaling NaNs of IEC 559 are not required (that is, have
       C9X overrides IEC 559 (and LIA-1) on this one point).
       3) Drop.]

       Proposal:

       -- Add to subclause 7.7 Mathematics <math.h>:

       The macros

          NANSF
          NANS
          NANSL

       are respectively float, double, and long double versions of
       signaling NaNs.  They are defined if and only if the
       implementation supports signaling NaNs for the indicated
       type.  They expand to a constant expression, suitable for
       static and aggregate initialization, representing an
       implementation-defined signaling NaN.

       -- Add a new paragraph after the NANS macros and before the
       number classification macros:

       The macros

         COPY_NANSF_SIGNALS
         COPY_NANS_SIGNALS
         COPY_NANSL_SIGNALS

       expand to boolean constants to indicate whether copying,
       such as by assignment, a signaling NaN without a change of
       format signals the invalid operation exception.  They are
       defined if and only if the implementation supports signaling
       NaNs for the indicated type.

       [ISSUE: Should these have three values: never(0), always(1),
       and sometimes(-1)?  I can see a need for sometimes, as it
       may depend upon code optimization level.]

       [ISSUE: Do we need a macro for each floating format?  I
       assume some implementations do assignment as a load/store
       into/from long double registers, so floats and doubles would
       signal, but long doubles would not.]

       [ISSUE: Do we need macros to indicate if passing a signaling
       NaN by value (assigning argument to parameter) in a function
       call signals invalid?]

       [ISSUE: Do we need macros to indicate if returning a
       signaling NaN from a function call signals invalid?]

       -- Add to the list of macros for number classification in
       subsection 7.7 <math.h> after FP_NAN:

       FP_NANS

       -- In fpclassify (subsection 7.7.2.1), change:

         The fpclassify macro classifies its argument value as NaN,
         infinite,

       to:

         The fpclassify macro classifies its argument value as
         signaling NaN, quiet NaN, infinite,

       -- [ISSUE: Do we need a function similar to 7.7.11.2 nan
       function to create signaling NaN?  It would return void and
       be passed the address of where to store the NANSF/NANS/NANSL
       as well as the pointer to the n-char-sequence.  I believe
       that none of IEC 559, LIA-1, and LIA-2 require such a
       function.]

       -- In F.2 Types, change:

         247. A non-IEC 559 long double type must provide
              infinities and NaNs, as its values must include all
              double values.

       to:

         247. A non-IEC 559 long double type must provide
              signaling NaNs, quiet NaNs, and infinities, as its
              values must include all double values.

       -- In F.2.1 Infinities, signed zeros, and NaNs, change:

           This specification does not define the behavior of
           signaling NaNs.248 It generally uses the term NaN to
           denote quiet NaNs.  The NAN and INFINITY macros and the
           nan function in <math.h> provide designations for IEC
           559 NaNs and infinities.

       to:

           This specification does define the behavior of signaling
           NaNs since they are a required feature of IEC 559.248 It
           generally uses the term NaN to denote quiet NaNs.  The
           NAN, NANSF, NANS, NANSL and INFINITY macros and the nan
           function in <math.h> provide designations for IEC 559
           NaNs and infinities.

       -- In Subsection F.3, last item, add FP_NANS to the
       list of classification macros.  Also, replace: "IEC 559
       (except that fpclassify does not distinguish signaling from
       quiet NaNs)" with "IEC 559.  The signbit and fpclassify
       macros do not raise invalid for signaling NaNs." in the same
       paragraph.

       -- In subsection F.3, add: The isnan macro shall (should?)
       not raise invalid for signaling NaNs.

       -- In subsection F.9, change:

         Generally, one-parameter functions of a NaN argument
         return that same NaN and raise no exception.

       to:

         Generally, two-parameter functions with either or both
         arguments being a signaling or quiet NaN return the sum of
         those two arguments.  If either argument was a signaling NaN,
         invalid is raised.  That way the function acts like a basic
         arithmetic operation for NaN propagation.

         Generally, one-parameter functions of a signaling NaN
         argument return that signaling NaN made quiet and raise
         invalid.  None of the standards specify how a signaling
         NaN is replaced by a quiet NaN; just that a quiet NaN
         shall be the result if no trap happens.  The function f(x)
         should use x+x as the means to make a signaling NaN quiet,
         so as to act like a basic arithmetic operation for NaN
         propagation. 

         Generally, one-parameter functions of a quiet NaN argument
         return that same quiet NaN and raise no exception.

       --

       In subsection F.8.2 Expression transformations, change:

       256. Strict support for signaling NaNs - not required by
           this specification - would invalidate these and other
           transformations that remove arithmetic operators.

       to:

       256. Strict support for signaling NaNs would invalidate
           these and other transformations that remove arithmetic
           operators.

       -- Add to F.9.1.4 The atan2 function before the item on
       (quiet) NaNs:

        - atan2(y,x) returns y/x and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then atan2 returns
          that NaN made quiet and raises invalid.

       -- Add to F.9.4.2 The hypot function before the item on
       (quiet) NaNs:

        - hypot(x,y) returns x+y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then hypot returns
          that NaN made quiet and raises invalid.

       -- Add to F.9.4.3 The pow function before the item on
       (quiet) NaNs:

        - pow(x,y) returns x+y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then pow returns
          that NaN made quiet and raises invalid.

          [ISSUE: is pow(NANS,0.0) invalid or 1.0?]

       -- Add to F.9.7.1 The fmod function before the item on
       (quiet) NaNs:

        - fmod(x,y) returns x/y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then fmod returns
          that NaN made quiet and raises invalid.

       -- Add to F.9.8.3 The nextafter function before the item on
       (quiet) NaNs:

        - nextafter(x,y) returns x+y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then nextafter returns
          that NaN made quiet and raises invalid.

       -- Add to F.9.9.1 The fdim function before the item on
       (quiet) NaNs:

        - fdim(x,y) returns x+y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then fdim returns
          that NaN made quiet and raises invalid.

       -- Add to F.9.9.2 The fmax function before the item on
       (quiet) NaNs:

        - fmax(x,y) returns x+y and raises invalid if both
          arguments are signaling NaNs.

        - If one argument is a signaling NaN then fmax returns
          that NaN made quiet and raises invalid.

          [ISSUE: That last item differs from fmax(1.0,NAN) being
          1.0 instead of NAN.]

       -- I/O

       [ISSUE: Do we need to specify printing Signaling NaNs?  I
       believe that there is no assurance that a NANS can be
       passed to printf, therefore, the NANS cannot be detected to
       be printed.  We could make it implementation defined.]

       [ISSUE: Do we need to specify inputing Signaling NaNs?  I
       believe that there is no assurance that a NANS can be
       returned from strtod.  On the other hand, scanf could store
       a NANS via the pointer passed to scanf.  We could make
       store via pointer be required and store via return be
       implementation defined.]

       IEEE-854 in section 5.6 Floating-Point <--> Decimal String
       Conversion has:

	    The letters "NaN," case insensitive, optionally
	    preceded by an algebraic sign, should be the first
	    characters of a string representing a NaN.

	    Unless recognized as a quiet NaN on input, an
	    input NaN should become a signaling NaN.

       These are enhancements to IEEE-754 which has "NaNs encoded
       in decimal strings are not specified in this standard."

       -- Complex

       [ISSUE: In G.5.1 Multiplicative operators, is:
          [#4] A complex or imaginary value with at least one
          infinite part is regarded as an infinity (even if its
          other part is a NaN).
       still true if the NaN is a signaling NaN?]

       -- Uninitialized variable usage detection

       For NaNs to be useful as a means to detect the use of a
       floating-point value before it has been assigned a value
       would require a change to the existing C language.  Since
       the bit pattern of all ones in a IEEE-754 single and double
       are NaNs (the same is true for most, if not all, double
       extended formats), setting static, automatic, and heap
       floating-point variables to all ones would produce NaNs
       in place of undefined values.  Unfortunately, the all ones
       bit pattern is not required to be a signaling NaN, it can be
       a quiet NaN.  This idea also goes against the existing C where
       some variables are set to zero at creation.  If this were
       supported, it would have to be under a pragma so that the
       user can ask for this all ones as well as the current zeros.