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: tydeman@tybor.com 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 : 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 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 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 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.