ISO/ IEC JTC1/SC22/WG14 N750

*                     Document Number:  WG14 N750/J11 97-113


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

*      Title: LIA-1 Binding: LIA-1 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-16
       Proposal Category:
          __ Editorial change/non-normative contribution
          __ Correction
          Y_ 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: Very little.  Sun, and maybe others, print messages
       at program termination if any IEC 559 flags are raised.  That
       is one small part of this proposal.
       Target Audience: Programmers writing programs that perform a
       significant amount of numeric processing.___________________
       Related Documents (if any):
        WG14/N758 C9X and LIA-1 informative annex,
        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/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
       Proposal Attached: _Y Yes __ No, but what's your interest?

       Abstract: This part of the C9X+LIA binding discusses the
       binding of LIA-1 to C, that is, what it takes to have a LIA-1
       conformant implementation.

       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 6.8.8 Predefined macro names:

       The following macro name is defined if and only if the
       implementation conforms to Annex H.

              __STDC_LIA_1__ The decimal constant 1.


*      -- Modify annex H Language Independent Arithmetic.
       Either replace with or merge the following.

                               Annex H
                             (normative)

                    Language Independent Arithmetic

**     H.1 Introduction

       -Replace the introduction with:

       This annex specifies C language support for the ISO/IEC
       10967-1 language independent arithmetic (LIA-1) standard.
       An implementation that defines __STDC_LIA_1__ conforms to
       the specification in this annex.  Where a binding between
       the C language and LIA-1 is indicated, the LIA-1-specified
       behavior is adopted by reference, unless stated otherwise.

       An implementation shall conform to all the requirements of
       LIA-1 (ISO 10967-1:1994) unless otherwise specified in this
       clause.

       LIA-1 specifies a parameterized model of arithmetic
       computation.  The purpose of LIA-1 is to provide a known
       environment in conforming implementations across platforms
       and languages for applications requiring numeric
       computation.  Overall, the C binding of LIA-1 doesn't affect
       existing programs but new programs will achieve a higher
       degree of portability on LIA-1 systems.  The impact of the
       changes are: adding some macros, adding a handful of library
       functions, detecting arithmetic exceptions, and requiring
       the implementation to document certain features of its
       arithmetic.

       -Replace LIA-1-like with LIA-1 throughout the annex.

**     H.2 Types

***    H.2.2 Integral Types

       -Replace no integer types conform with:

       The C integral types int, long, long
       long, unsigned int, unsigned long,
       unsigned long long conform to LIA-1[footnote].

       [footnote]: The conformity of short and char
       (plain, signed or unsigned) is not relevant since values of
       these types are promoted to int (plain, signed or
       unsigned) before computations are done.

****   H.2.2.1 Integer Parameters

       -Add another parameter:

       modulo         INT_OUT_OF_BOUNDS.

       The parameter modulo is always true for the unsigned types,
       and is not provided for those types.  The parameter modulo
       is true when INT_OUT_OF_BOUNDS is 1 (wrap) or false when
       INT_OUT_OF_BOUNDS is 2 (notify) and covers all LIA-1
       conformant signed types.  The implementation picks the value
       of modulo.  It is implementation defined if the user can
       change the value of modulo.

****   H.2.2.2 Integer Operations

       -Add the following operations:

       modaI          modulo(x, y), lmodulo(x, y), llmodulo(x, y).

       modpI          No binding.

       signI          sgn(x), lsgn(x), llsgn(x).

***    H.2.3 Floating-Point Types

       -Replace no floating-point types conform with:

       The floating types float, double, and long
       double conform to LIA-1.

****   H.2.3.1 Floating-Point Parameters

       -Add some more parameters:

       denorm         FLT_SUBNORMAL, DBL_SUBNORMAL, LDBL_SUBNORMAL.

       iec_559        FLT_IEC_559, DBL_IEC_559, LDBL_IEC_559.

       The *_IEC_559 macros represent booleans and have values 1 or
       0.

       -Add some more derived constants:

       fmin           FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN.

       rnd_error      FLT_RND_ERR.

       If *_SUBNORMAL is not 1, then *_TRUE_MIN is the same as
       *_MIN.

       The FLT_RND_ERR macro must be less than or equal to 1.0

       Rounding error FLT_RND_ERR depends upon rounding mode
       FLT_ROUNDS.  Rounding error will be constant
       expression suitable for use in #if if and only if
       FLT_ROUNDS is constant.


****   H.2.3.2 Floating-Point Operations

       -Add additional operations as functions:

       signF          fsgnf(x), fsgn(x), fsgnl(x).

       fractionF      fracrepf(x), fracrep(x), fracrepl(x).

       succF          fsuccf(x), fsucc(x), fsuccl(x).

       predF          fpredf(x), fpred(x), fprecl(x).

       ulpF           ulpf(x), ulp(x), ulpl(x).

       truncF         trunctof(x, n), truncto(x, n), trunctol(x, n).

       roundF         roundtof(x, n), roundto(x, n), roundtol(x, n).


***    H.2.4 Type Conversions

       -Add the following macro calls:

       cvtF->I        icvt(x), lcvt(x), llcvt(x),
                      uicvt(x), ulcvt(x), ulcvt(x).


**     H.3 Notification

****   H.3.1.1 Indicators

       -Split the 'undefined' into undefined and pole for the
       existing floating-point indicators.

       -Add the following:

       The following integer 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).

       undefined           INT_INVALID.

       pole                INT_DIVBYZERO.

       integer_overflow    INT_OVERFLOW.

       Undefined covers zero/zero, while pole covers finite
       non-zero/zero.  For implementations that cannot distinguish
       the two cases, pole is used.  The macros 
       DISTINGUISH_INT_DIV_BY_ZERO and DISTINGUISH_FP_DIV_BY_ZERO
       are the means to indicate if zero/zero can be distinguished
       from finite non-zero/zero for integral types and floating-point
       types respectively.  The use of pole is a deviation from LIA-1.

       The macro FP2INT_OF_LARGE is used, in place of INT_OVERFLOW
       as required by LIA-1, to document how conversion of large
       floating-point values to out-of-bounds integral values will
       notify.  FP2INT_OF_LARGE shall be either INT_OVERFLOW or
       FE_INVALID.

       For example, the LIA-1 indicator subset

            {floating_overflow, underflow, integer_overflow}

       would be denoted by the expression

            FE_OVERFLOW | FE_UNDERFLOW | INT_OVERFLOW

       The integer indicator interrogation and manipulation
       operations are:

       set_indicators      ieraiseexcept(i).

       clear_indicators    ieclearexcept(i).

       test_indicators     ietestexcept(i).

       current_indicators  ietestexcept(INT_ALL_EXCEPT).

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

       When notification via flags is chosen, then whenever a LIA-1
       exceptional value would result, the appropriate indicator
       shall be set (sometime before program accesses the status
       flag or terminates) and an implementation defined
       continuation value used.

       At program termination, if any LIA-1 indicator is set:

       - the implementation shall send an unambiguous and "hard to
       ignore" message (see LIA-1 subclause 6.1.2) to stderr.  The
       message should identify the indicators set.

       - next, the stderr stream shall then be flushed and
       stderr closed.  It is implementation defined if other
       open output streams are flushed, other open streams closed,
       and any files created by the tmpfile function are
       removed.

       - finally, control is returned to the host environment.  An
       implementation-defined form of the status unsuccessful
       termination is returned.

****   H.3.1.2 Traps

       Trap first exception and terminate shall include the
       following.

       When notification via traps is chosen, then whenever a LIA-1
       exceptional value would result, the implementation shall
       send a message to stderr (sometime before any other
       output).  The message sent to stderr should identify
       the cause of the notification and the operation responsible.

       Next, the stderr stream shall then be flushed and
       stderr closed.  It is implementation defined if other
       open output streams are flushed, other open streams closed,
       and any files created by the tmpfile function are removed.

       Finally, control is returned to the host environment.  An
       implementation-defined form of the status unsuccessful
       termination is returned.

***    H.3.2 User selection

       The implementation shall provide a means for a user or
       program to select among the alternative notification
       mechanisms provided (see LIA-1 subclause 6.3).  The
       LIA_NOTIFY pragma is the method used.  LIA_NOTIFY FLAGS and
       LIA_NOTIFY TRAP are the LIA-1 required conformant
       mechanisms.  LIA_NOTIFY UNDEF and LIA_NOTIFY IGNORE are not
       LIA-1 conformant.

**     H.4 <stdlia.h>

       This subclause contains specification of <stdlia.h> facilities
       that is required for LIA-1 implementations.

***    H.4.1 Nearest integer macros

       The macros used to convert from floating-point types to
       signed integral types are defined for out-of-bounds results
       in both wrapping and trapping modes.  The use of
       FP2INT_OF_LARGE instead of INT_OVERFLOW is a deviation from
       LIA-1.

****   H.4.1.1 The icvt macro

       If the rounded value is outside the range of int and
       INT_OUT_OF_BOUNDS is 1 (wrap), the rounded value is
       wrapped modulo (INT_MAX-INT_MIN+1).

       If the rounded value is outside the range of int and
       INT_OUT_OF_BOUNDS is 2 (notify), the numeric result
       is unspecified and FP2INT_OF_LARGE is raised.

****   H.4.1.2 The lcvt macro

       If the rounded value is outside the range of long and
       INT_OUT_OF_BOUNDS is 1 (wrap), the rounded value is
       wrapped modulo (LONG_MAX-LONG_MIN+1).

       If the rounded value is outside the range of long and
       INT_OUT_OF_BOUNDS is 2 (notify), the numeric result
       is unspecified and FP2INT_OF_LARGE is raised.

****   H.4.1.3 The llcvt macro

       If the rounded value is outside the range of long
       long and INT_OUT_OF_BOUNDS is 1 (wrap), the
       rounded value is wrapped modulo
       (LLONG_MAX-LLONG_MIN+1).

       If the rounded value is outside the range of long
       long and INT_OUT_OF_BOUNDS is 2 (notify), the
       numeric result is unspecified and FP2INT_OF_LARGE is
       raised.

***    H.4.2 Modulo functions

****   H.4.2.1 The modulo function

       modulo(i,0) raises INT_INVALID and returns an
       unspecified value

****   H.4.2.2 The lmodulo function

       lmodulo(i,0) raises INT_INVALID and returns an
       unspecified value

****   H.4.2.3 The llmodulo function

       llmodulo(i,0) raises INT_INVALID and returns an
       unspecified value