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 ; 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 * 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: ), 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 rather than in the logical place that they belong (, , , , ). 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 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 or ? It is easier wording-wise to put them in 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 has been included? Must 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 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 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 is included. That is, is a conditionaly normative header. Therefore, I believe that 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? or ? - --- 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/