From willemw@komp  Thu Sep  4 16:57:28 1997
Received: from komp.ace.nl (komp.ace.nl [193.78.104.90]) by dkuug.dk (8.6.12/8.6.12) with SMTP id QAA10067 for <sc22wg11@dkuug.dk>; Thu, 4 Sep 1997 16:57:28 +0200
Received: by komp.ace.nl with SMTP id AA27884 (1.14/2.17);
	  Thu, 4 Sep 97 16:55:40 +0200 (MET)
To: sc22wg11@dkuug.dk
Subject: WG11 N440 (7 of 7): LIA-1 binding for C: Rationale
Date: Thu, 04 Sep 97 16:55:39 N
Message-Id: <27882.873384939@komp>
From: Willem Wakker <willemw@komp.ace.nl>


*                          Document Number:  WG14 N753/J11 97-116


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

*      Title: LIA-1 Binding: Rationale
       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-08-28
       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
          __ Language
          __ Preprocessor
          __ Library
             __ Macro/typedef/tag name
             __ Function
             __ Header
          Y_ Other (please specify)  Rational______________________
       Prior Art: C89.
       Target Audience: Programmers writing programs that perform a
       significant amount of numeric processing.___________________
       Related Documents (if any):
        WG14/N752 (LIA-1 Binding: Optional parts annex),
        WG14/N751 (LIA-1 Binding: 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 of LIA-1),
        WG14/N487 (LIA-1),
        WG14/N486 (LIA Overview),
        WG14/N463 (Impact of adding LIA-1)
       Proposal Attached: _Y Yes __ No, but what's your interest?

       Abstract: This is a list of open issues (to be resolved by
       the committee) followed by the Rational for the addition of
       LIA-1 to C9X.  As issues are resolved, they will be turned
       into rational.

       Proposal:

       It appears that the minimum that an implementation needs to
       do (with respect to code generation) to support LIA is:

         Define modulo (*_OUT_OF_BOUNDS) to be 1 (wrap) => no need
             to detect signed integer overflow.
         Detect integer divide by zero.
         Detect floating underflow, overflow, and divide by zero.
         When an exception happens:
         Either
             Set indicators and continue with a continuation value.
             Invoke a function similar to __lia_indicators() at
                 normal program termination.
         Or
             Print a "hard to ignore" message and terminate.
         Both alternatives for notification must be supported and
         the user must be able to choose which alternative to use.

       Since exceptions must be detected and acted upon, and we
       have heard complaints from some implementors that it is hard
       to do, a fundamental question that must be answered is: Is
       the proposed Annex H normative, conditional normative or
       informative? It is written up as conditional normative.

       --

       LIA-1 requires that arithmetic exceptions be detected.
       C requires that signal handlers honor SIGFPE.
       C requires signal handlers can terminate via longjmp.

       What is not required (by C or LIA-1) is that arithmetic
       exceptions map into the generation of SIGFPE (or any other
       SIG*).

       Should we require that arithmetic exceptions raise SIGFPE?
       Should there be a unique SIG* for each exception?

       Once we tie arithmetic exceptions to SIGPFE (or equivalent),
       then C has a useful trap handling mechanism.

       The proposal is written up assuming that arithmetic
       exceptions get mapped into SIGFPE.

       --

       Will we allow partial conformity (Annex B in LIA-1)?

       --

       General name space pollution.  There are many macros and
       functions that could conflict with existing user's code.  I
       am not an implementor, so do not have a vested interest in
       the names we chose, e.g., I am very willing to change the
       names.

       One way to solve pollution is to put all the new macros
       and functions into <stdlia.h> rather than in the logical place
       that they belong (<limits.h>, <float.h>, <math.h>, <stdlib.h>,
       <tgmath.h>).  That should allow existing code to
       continue to compile with a C9X compiler without change.

       A first pass at the proposal had them in the logical place
       (and that drew some complaints).

       The current proposal has them all in <stdlia.h> as name
       space pollution is a big concern with some members (do not
       break existing code just because it happens to be compiled
       with a C9X compiler).

       --

       The model representation of LIA and C9X floating-point
       numbers is: sign * p-digit fraction * base ** exponent,
       where fraction is in the range [ 1/FLT_RADIX ...  1.0 ).

       The model representation has nothing to do with the hardware
       representation.

       LIA has functions to get the exponent and the fraction from
       the model representation.  LIA also has functions to get the
       integer part and the fraction part of a value.

       So, for the value 3.1416 in base 10, the representation is
        + 0.31416 * 10 ** 1.

         1.0     = exponent of model representation
         0.31416 = fraction of model representation
         3.0     = integer part of value
         0.1416  = fraction part of value

       So, the 'fraction' of x could mean the fraction of the value
       or the fraction of the model representation.  Fraction of
       the model representation has other similar names: mantissa
       or significand.  From these names, the name of the function
       could be derived.  LIA recommends 'fract' for the fraction
       of the model representation and 'frcprt' for the fraction
       part of the value.  I chose 'fracrep' and 'fracval'.  Are
       there better choices?

       For non-zero finite numbers, 1/radix <= fracrep(|x|) < 1.

       --

       Should there be a function for exponent of the model
       representation ('exprep'), or, should it just be
       documentation that it is logb(x)+1?

       --

       Should there be a function for integer part of value
       ('intval'), or, should it just be documentation that it can
       be obtained via modf()?

       --

       Should there be a function for fraction part of value
       ('fracval'), or, should it just be documentation that it can
       be obtained via modf()?

       --

       Should fpred(-INFINITY) return -INFINITY or raise invalid
       and return a NaN?

       Should fpred(0.0) raise underflow?

       fpred(subnormal) does not raise underflow (unlike
       nextafter).  But, then, LIA-2 does not raise underflow for
       any math function that takes a subnormal and returns a
       subnormal, eg, sin(subnorm) is same subnorm w/o underflow.
       Their reason is underflow was already raised when the
       subnormal was created.  That reason is faulty for
       sin(DBL_TRUE_MIN) since it is an exact input value (not the
       result of previous arithmetic).  Also, the mathematical
       value of sin(subnorm) is not exactly the same subnorm, so
       the value returned is an inexact approximation of the true
       result.

       fpred and fsucc(subnorm) take an exact value and return an
       exact value.  There is not denormalization loss nor inexact,
       so underflow should not be raised.  That same statement
       should apply to nextafter (but does not, why?).

       --

       Should fsucc(+INFINITY) return +INFINITY or raise invalid
       and return a NaN?

       Should fsucc(0.0) raise underflow?

       fsucc(subnormal) does not raise underflow (unlike
       nextafter).

       --

       How best should sample atexit to print indicators at program
       termination be made normative?

       --

       Should rounding error be constant or track changes to
       rounding mode? I believe that it should be like FLT_ROUNDS
       (a function) and track the runtime changes.

       --

       Should integer flags be part of (or separate from) fp env.
       flags? I believe that the floating-point exception flags and
       the integer exception flags may have different status
       associated with the flags, hence, fexcept_t may not be able
       to hold the integer related information.

       --

       The definition of modulo (*_OUT_OF_BOUNDS) has been extended
       to include undefined to cover current C behavior: undefined
       vs wrapped vs notification.

       --

       The casts from floating to integral cannot be used (to meet
       LIA-1 requirements) as they truncate (round toward zero) and
       LIA-1 requires round to nearest.  LIA-1 also requires, if
       modulo = wrap, that integer overflow not be raised.  The
       lround() and lrint() family of functions cannot be used as
       they may raise FE_INVALID.

       It is assumed that there is a global integer control mode to
       indicate if signed integer types are wrapping or not.  That
       control mode will affect the behavior of the *cvt()
       functions.

       --

       Should the floating to integral conversion [*cvt()]
       operators be macros (similar to isless())? Or, is it better
       to have them be type-generic functions? Should they be in
       <stdlia.h> or <math.h>? It is easier wording-wise to put them
       in <math.h> if we want type-generic functions.

       --

       Should icvt(-0.0) return -0 (if it can be represented), else
       +0? The same question applies to lcvt and llcvt.

       --

       Should icvt(INFINITY) raise INT_INVALID or FE_INVALID? The
       same question applies to all the *cvt macros.  Since it is
       the integers that cannot represent infinity, it seems like
       it should be INT_INVALID.

       --

       Who determines if signed integers wrap or overflow: C9X,
       implementation, or user?

       LIA-1, in section A.5.1.0.2, says: Since modulo integers are
       dangerous, programmers should always have the option of
       using non-modulo (overflow checking) integers instead.

       The optional LIA_WRAP pragma allows the user to choose.
       Should this pragma be made normative?

       --

       What is scope of LIA_WRAP pragma? Statement, function, or
       translation unit?

       --

       Should there be a IENV_ACCESS pragma to allow the user to
       inform the implementation that the program might access the
       integer environment? I believe not, since, if the user does
       #pragma STDC LIA_NOTIFY FLAGS, they have told the
       implementation that the flags will be tested at program
       termination (at the least).

       --

       What is the meaning of #pragma STDC LIA_NOTIFY opt before
       <stdlia.h> has been included? Must <stdlia.h> be included to give
       it meaning? Should the include be removed from the synopsis?
M       I believe that all the pragmas should be independent of
       headers and should not have the include of a header in the
       synopsis section.

       --

       Is there interaction between FENV_ACCESS and LIA_NOTIFY
       pragmas? Does one imply the other?

       --

       Should fedisabletrap() return void (like feclearexcept), a
       boolean indicator (like fesetround), or the set of
       indicators that it supports? Same question for
       feenabletrap().

       --

       Should the ie*trap() and fe*trap() functions be merged into
       one set of (enable/disable/test)_trap() functions, along
       with FE_TRAP_* and INT_TRAP_* macros? For a minimal support
       of trapping (what is being proposed), there should be no
       problem having one set of functions.  But, if the standard
       or implementors were to add additional functions, similar to
       fegetexceptflag, but for traps, then the representation of
       floating-point traps might differ enough from integer traps
       to make implementation difficult or impossible.

       --

       Should we define syntax/semantics in Annex J for optional
       IEEE-754 trap functions: fesettraphandler(),
       fesavetraphandler(), ferestoretraphandler(),
       fependingtraps() or similar spelling?

       signal( SIGFPE, function ) is the equivalent of set trap
       handler.

       --

       Should the addition of SNAN* macros be moved from proposed
       Annex I to 7.7 <math.h> and Annex F (IEC 559)? Signaling
       NaNs are a required part of IEC 559, so to claim conformance
       to C and IEC 559, the language and the implementation need
       Signaling NaNs.  This is not a LIA-1 issue, but an IEC 559
       issue.

       --

       How do we do "Hard to ignore" indicators message at
       termination?

       Print to stderr is the suggested way.

       --

       It is assumed that the integer and floating-point
       environments each consist of a control word and a status
       word.  The status word contains bits (sticky flags) to
       indicate the state of past operations.  The status word and
       control word need not be hardware registers, they may be in
       memory and maintained by system software.

       The floating-point environment consists of:

         status
           sticky flags
             invalid
             div-by-zero
             overflow
             underflow
             inexact
           optional
             current operation being performed
             exception(s) of current operation
             exception(s) still pending
             operand values
             destination's precision
             rounded result

         control
           rounding
           precision (optional)
           trap enable/disable (optional)
             invalid
             div-by-zero
             overflow
             underflow
             inexact

       The integer environment consists of:

         status
           sticky flags
             invalid
             div-by-zero
             overflow
           optional
             current operation being performed
             exception of current operation
             exception(s) still pending
             operand values
             destination's precision
             wrapped result

         control
           trap enable/disable (optional)
             invalid
             div-by-zero
             overflow

       The integer trap enable/disable control bits also indicate
       if notification is via a trap handler (enabled) or via
       setting a flag and returning a wrapped result (disabled).

       --

       What about <stdbool.h> for booleans?

       As I understand N738 and what we did in London this past
       June, bool, true, and false are keywords if and only if
       <stdbool.h> is included.  That is, <stdbool.h> is a
       conditionaly normative header.

       Therefore, I believe that <stdlia.h> cannot depend upon bool,
       true, and false.  I am willing to change that belief if the
       committee directs me to.

       -- 

       What is the name of the new header?  <lia.h> or <stdlia.h>? 


- ---
Fred J. Tydeman    +1 (512) 255-8696   Tydeman Consulting
3711 Del Robles    tydeman@tybor.com   Programming, testing, numerics
Austin, Texas 78727                    Voting member of X3J11 (ANSI "C")
USA            Sample C9X+FPCE tests:  ftp://jump.net/pub/tybor/
