* 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: to , 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: , 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, code sample 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 This subclause contains specification of 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