ISO/ IEC JTC1/SC22/WG14 N758

*                     Document Number:  WG14 N758/J11 97-121


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

*      Title: C9X and LIA-1 informative annex.
       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-22
       Proposal Category:
          Y_ Editorial change/non-normative contribution
          __ Correction
          __ New feature
          __ Addition to obsolescent feature list
          __ Addition to Future Directions
          __ Other (please specify)  ______________________________
       Area of Standard Affected:
          __ Environment
          Y_ Language
          __ Preprocessor
          __ Library
             __ Macro/typedef/tag name
             __ Function
             __ Header
          Y_ Other (please specify)  Annex_________________________
       Prior Art: None.____________________________________________
       Target Audience: Programmers writing programs that perform a
       significant amount of numeric processing.___________________
       Related Documents (if any):
        WG14/N756 LIA-1 Binding: Arithmetic exception => SIGFPE,
        WG14/N755 LIA-1 Binding: <fenv.h> to <stdmath.h>,
        WG14/N753 LIA-1 Binding: Rationale,
        WG14/N752 LIA-1 Binding: Optional parts annex,
        WG14/N751 LIA-1 Binding: Combined LIA-1 + IEC-559 annex,
        WG14/N750 LIA-1 Binding: LIA-1 annex.
        WG14/N749 LIA-1 Binding: <stdlia.h>,
        WG14/N748 LIA-1 Binding: Adding 'pole' from LIA-2,
        WG14/N747 IEC 559 Binding: Signaling NaNs,
        WG14/N528 C Binding for LIA-1,
        WG14/N488 LIA-2 (math library),
        WG14/N487 LIA-1 (arithmetic),
        WG14/N486 LIA Overview,
        WG14/N463 Impact of adding LIA-1,
        WG14/N461 C Binding of LIA-1,
        Defect Report 152 longjmp from a signal handler,
        Defect Report 099 Narrowing of FP expression,
        Defect Report 056/063 Accuracy of floating-point,
        Defect Report 036 Representation of FP constants,
        Defect Report 025 Floating-point representation.
       Proposal Attached: _Y Yes __ No, but what's your interest?

       Abstract: This is an informative annex to C9X to document
       the extent to which the C language currently supports the
       LIA-1 requirements.  It is expected that this annex will be
       replaced by an amendment to C9X in a year or two that will
       be the binding of LIA-1 to C9X.

       The other proposals should be considered a starting point
       of the LIA-1 amendment.

       Proposal:

       Note: The '*' characters in the lefthand column are not part
       of the proposal (they are useful for emacs M-x outline mode)

       In the following, bold text, italic text,
       <TT>code sample</TT> are the conventions used to indicate
       text different from normal.

*      -- Add to Annex A Bibliography:

       ISO/IEC 10967-1:1994(E) Information technology --
       Language independent arithmetic -- Part 1: Integer and
       floating point arithmetic.

*      -- Add a new annex, here called H, after annex G IEC
       559-compatible complex arithmetic:

                               Annex H
                            (informative)

                    Language Independent Arithmetic

**     H.1 Introduction

       
       This annex documents the extent to which the C language
       currently supports the ISO/IEC 10967-1 Language Independent
       Arithmetic, part 1, integer and floating-point arithmetic
       (LIA-1) standard.  It is expected that this annex will
       eventually be replaced, by an amendment to the C language,
       with a binding between LIA-1 and C.  Part of the delay is
       due to differences between LIA-1 and LIA-2 on the meaning of
       pole and undefined exceptions. 

       For the rest of this annex, the term LIA-1-like will be used
       to denote a C type that meets a LIA-1 type except for the
       lack of notification of exceptional arithmetic operations.

**     H.2 Types

***    H.2.1 Boolean Type

       The LIA-1 data type Boolean is implemented by the C data
       type bool with values of true and
       false, all from <stdbool.h>.

***    H.2.2 Integral Types

       None of the unsigned or signed C integral types conform to
       LIA-1 because they all lack the LIA-1 exceptional values
       integer_overflow and undefined.[Footnote]

       [Footnote: Exceptional values are used as part of the LIA-1
       defining formalism only.  They do not represent values of
       any data types.  There is no requirement that they be
       represented or stored in a computing system.  They are not
       used in subsequent arithmetic operations.

       The values Not-a-number and infinity of IEC 559 are not
       considered exceptional values for LIA-1.  They are
       "continuation values" -- a value used in lieu of an
       exceptional arithmetic operation; after a status flag has
       been set to record the notification.]

       The parameters for the LIA-1-like integer data types can be
       accessed by the following:

       maxint         INT_MAX, LONG_MAX, LLONG_MAX,
                      UINT_MAX, ULONG_MAX, ULLONG_MAX.

       minint         INT_MIN, LONG_MIN, LLONG_MIN.

       The parameter bounded is always true, and is not provided.
       The parameter minint is always 0 for the unsigned types, and
       is not provided for those types.

****   H.2.2.2 Integer Operations

       The integer operations on LIA-1-like integer types are the
       following:

       addI           x + y.

       subI           x - y.

       mulI           x * y.

       divI, divtI    x / y.

       remI, remtI    x % y.

       negI           - x.

       absI           abs(x), labs(x), llabs(x).

       eqI            x == y.

       neqI           x != y.

       lssI           x < y.

       leqI           x <= y.

       gtrI           x > y.

       geqI           x >= y.

       where x and y are expressions of the same integral type.

***    H.2.3 Floating-Point Types

       None of the C floating-point types conform to LIA-1 because
       they all lack the LIA-1 exceptional values underflow,
       floating_overflow, and undefined.

****   H.2.3.1 Floating-Point Parameters

       The parameters for a LIA-1-like floating point data type can
       be accessed by the following:

       r              FLT_RADIX.

       p              FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG.

       emax           FLT_MAX_EXP, DBL_MAX_EXP, LDBL_MAX_EXP.

       emin           FLT_MIN_EXP, DBL_MIN_EXP, LDBL_MIN_EXP.


       The derived constants for the LIA-1-like floating point
       types are accessed by the following:

       fmax           FLT_MAX, DBL_MAX, LDBL_MAX.

       fminN          FLT_MIN, DBL_MIN, LDBL_MIN.

       epsilon        FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON.

       rnd_style      FLT_ROUNDS.

       [Note: Defect Report 56/63, still open, is about the
       accuracy of floating-point arithmetic, a concern of LIA-1
       and LIA-2.  Defect Report 25 is about floating-point
       representation; has been answered, but did not result in a
       change to the standard, may need to be revisited.  Defect
       Report 36 dealing with representation of floating-point
       constants may need to be revisited for LIA-2.  This Note is
       not intended to be printed in the standard.]

****   H.2.3.2 Floating-Point Operations

       The floating-point operations on LIA-1-like floating-point
       types are the following:

       addF           x + y.

       subF           x - y.

       mulF           x * y.

       divF           x / y.

       negF           - x.

       absF           fabsf(x), fabs(x), fabsl(x).

       exponentF      1.f+logbf(x), 1.0+logb(x), 1.L+logbl(x).

       scaleF         scalbnf(x, n), scalbn(x, n), scalbnl(x, n).
                      scalblnf(x, li), scalbln(x, li), scalblnl(x, li).

       intpartF       modff(x, &y), modf(x, &y), modfl(x, &y).

       fractpartF     modff(x, &y), modf(x, &y), modfl(x, &y).

       eqF            x == y.

       neqF           x != y.

       lssF           x < y.

       leqF           x <= y.

       gtrF           x > y.

       geqF           x >= y.

       where x and y are expressions of the same floating point
       type, n is of type int, and li is of type long int.

****   H.2.3.3 Rounding Styles

       The C Standard requires all floating types use the same
       radix and rounding style, so that only one identifier for
       each is provided in the LIA-1 binding.

       The FLT_ROUNDS [footnote] parameter corresponds to the LIA-1
       rounding styles:

           truncate       FLT_ROUNDS == 0.

           nearest        FLT_ROUNDS == 1.

           other          FLT_ROUNDS != 0 && FLT_ROUNDS != 1.

       [footnote] The definition of FLT_ROUNDS has been extended to
       cover the rounding style used in all LIA-1 operations, not
       just addition.  FLT_ROUNDS does not apply to type conversions.

***    H.2.4 Type Conversions

       The LIA-1-like type conversions are the following type casts:

       cvtI'->I       (int)i, (long)i, (long long)i,
                      (unsigned int)i, (unsigned long)i,
                      (unsigned long long)i.

       cvtF->I        (int)round(x),
                      (long)round(x),
                      (long long)round(x),
                      (unsigned int)round(x),
                      (unsigned long)round(x),
                      (unsigned long long)round(x).

       cvtI->F        (float) i, (double) i, (long double) i.

       cvtF'->F       (float) x, (double) x, (long double) x.

       In the above conversions from floating to integral, the use
       of round() can be replaced with rint() or nearbyint() as
       long as the current rounding direction is to nearest.

       C's conversions (type casts) from floating-point to integral
       do not meet LIA-1 as LIA-1 requires round to nearest and C
       requires round to zero, also known as truncate.

       None of C's floating-point to integral conversion functions,
       lrint(), llrint(), lround(), and llround(), meet LIA-1's
       requirements as the result is unspecified if the rounded
       value is outside the integral range and also a range error may
       happen.

       C's conversions (type casts) from floating-point to
       floating-point do not meet LIA-1 as LIA-1 requires round to
       nearest and C leaves it as implementation defined as to the
       rounding function.

       C's conversions (type casts) from integral to floating-point
       do not meet LIA-1 as LIA-1 requires round to nearest and C
       leaves it as implementation defined as to the rounding
       function.

       C's round(), trunc(), ceil(), floor(), rint() and
       nearbyint() are not covered by LIA-1 as they are not type
       conversions.


**     H.3 Notification

       Notification is the process by which a user or program is
       informed that an arithmetic operation cannot be performed.
       Specifically, a notification shall occur when any arithmetic
       operation returns an exceptional value as defined in LIA-1
       clause 5.

***    H.3.1 Notification alternatives

       The implementation shall provide at least the following two
       alternatives for handling of notifications: setting
       indicators or trap and terminate.

       C does not require LIA-1 notification.  However, to the
       extent that notification occurs in implementations that
       support it, it would be via SIGFPE (for traps) and
       FE_INVALID, FE_DIVBYZERO, FE_OVERFLOW, FE_UNDERFLOW (for
       indicators).

       The notification alternative selected may influence code
       generation.  Because of this, an implementation need only
       support a given alternative for the entire program.  An
       implementation may support the ability to switch between
       notification alternatives during execution, but is not
       required to do so.  An implementation can provide separate
       selection for each kind of notification, but this is not
       required.

       C does not require any of those alternatives.  "Trap and
       terminate" is a good description of the default handling of
       SIGFPE for some C implementations.

****   H.3.1.1 Indicators

       The following floating-point indicators shall be provided.
       They shall be clear at the start of the program.  They are
       set when any arithmetic operation returns an exceptional
       value as defined in LIA-1 clause 5.  Once set, an indicator
       shall be cleared only by explicit action of the program
       (that is, they are sticky).

       The following mapping is for LIA-1-like floating-point
       types:

       undefined           FE_INVALID, FE_DIVBYZERO

       floating_overflow   FE_OVERFLOW.

       underflow           FE_UNDERFLOW.

       The values representing individual indicators shall be
       distinct non-negative powers of two.  The empty set is
       denoted by 0.  Other indicator subsets are named by
       combining individual indicators using bit-or.

       The floating-point indicator interrogation and manipulation
       operations are:

       set_indicators      feraiseexcept(i)

       clear_indicators    feclearexcept(i)

       test_indicators     fetestexcept(i)

       current_indicators  fetestexcept(FE_ALL_EXCEPT)

       where i is an expression of type int representing a
       LIA-1 indicator subset.

       C does not require any of those indicators.  C does support,
       via <fenv.h>, indicators for IEC 559 exceptions.  Those same
       indicators could be used for other floating-point hardware.

       C does not require that at program termination if any
       indicator is set the implementation shall send an
       unambiguous and "hard to ignore" message (see LIA-1
       subclause 6.1.2)

       LIA-1 does not make the distinction between floating-point
       and integer for undefined.  This documentation is making
       that distinction because <fenv.h> only covers the
       floating-point indicators.

****   H.3.1.2 Traps

       The implementation shall provide an alternative of
       notification through termination with a ``hard-to-ignore''
       message (see LIA-1 subclause 6.1.3).

       C does require that SIGFPE be the signal
       corresponding to arithmetic exceptions, if there is any
       signal raised for them.

       C has signal handlers (both implementation provided default
       and user provided) for SIGFPE, but C has no
       requirement that arithmetic exceptions trap. When arithmetic
       exceptions do trap, C's signal-handler mechanism supports
       trap and terminate (either default implementation behavior
       or user replacement for it) and trap and resume, at the
       programmer's option.

       But, it appears from the response to Defect Report 152 that
       a signal handler for SIGFPE invoked by means other
       than raise that does longjmp, exit,
       abort, or return is undefined behavior.