Document Number: WG14 N749/J11 97-112 C9X Revision Proposal ===================== Title: LIA-1 Binding: <stdlia.h> 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-21 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 __ Language __ Preprocessor Y_ Library Y_ Macro/typedef/tag name Y_ Function Y_ Header __ Other (please specify) ______________________________ Prior Art: None known. 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/N750 LIA-1 Binding: LIA-1 annex, WG14/N748 LIA-1 Binding: Adding 'pole' from LIA-2, WG14/N747 IEC 559 Binding: Signaling NaNs, WG14/N693 Type-Generic Math Functions, 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: These changes are the fundamental changes to C to allow support of ISO 10967-1 (LIA-1). They are being added in their own header <stdlia.h> 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.6 Pragma directive: #pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP } and add to the list of forward references: the LIA_NOTIFY pragma (7.x.4.1.1) * -- Add a new library section (here called 7.x) **7.x Notification and additional utilities <stdlia.h>.The header <stdlia.h> declares several macros and functions to support Language Independent Arithmetic. These are additional limits (characteristics of the integer and floating-point types), general integer utilities, mathematical functions, notification and access to the integer environment. Theinteger environmentrefers collectively to any integer status flags and control modes supported by the implementation[footnote]. Aninteger status flagis a system variable whose value is set as a side effect of the arithmetic to provide auxiliary information. Aninteger control modeis a system variable whose value may be set by the user to affect the subsequent behavior of the arithmetic. [footnote]. This header is designed to support the notification indicators (here called exception status flags) required by LIA-1, and other similar integer state information. Also it is designed to facilitate code portability among all systems. ***7.x.1 LimitsSeveral macros are declared to provide additional information beyond<limits.h>and<float.h>about the characteristics of the integer and floating-point types. All integral values in the <stdlia.h> header, shall be constant expressions suitable for use in #if preprocessing directives; all floating values shall be constant expressions. Most floating-point related macros have separate names for all three floating-point types. ****7.x.1.1 Integer limitsThe treatment of out-of-bounds results 0 undefined behavior 1 wrap (similar to unsigned) 2 notification for the signed integer typesint,longandlong longare characterized byINT_OUT_OF_BOUNDS****7.x.1.2 Floating-point limitsThe values given in the following list shall be replaced by implementation-defined expressions that shall be equal or lesser in magnitude (absolute value) to those shown, with the same sign: -- maximum rounding error of, at least the operations, +, -, *, and /, in terms of Units in Last Place (ULPs), for each floating-point type,FLT_RND_ERR7.0 In general, for normal results, the rounding error, re, is defined by: | tr - cr | <= re * ulp(cr) where tr = infinitely precise true result cr = computed result For the full details, including difference between normals and subnormals, see LIA-1 subclause 5.2.8 Rounding constants. The values given in the following list shall be replaced by implementation-defined expressions that shall be equal or greater in magnitude (absolute value) to those shown, with the same sign: -- minimum positive floating-point number, b**emin-p if subnormalized numbers are supported, else b**emin-1,FLT_TRUE_MIN1E-37DBL_TRUE_MIN1E-37LDBL_TRUE_MIN1E-37 The level of support for subnormalized numbers is characterized by the values -1 indeterminable 0 not supported 1 fully supported 2 treated as zero for the floating types float, double, long doubleFLT_SUBNORMALDBL_SUBNORMALLDBL_SUBNORMALrespectively. All other negative values for*_SUBNORMALcharacterize implementation-defined behavior. The values given in the following list shall be replaced by implementation-defined expressions: -- boolean value (0 or 1) to indicate if the corresponding type conforms to IEC 559,FLT_IEC_559DBL_IEC_559LDBL_IEC_559Example 2 in<float.h>is supplemented with these:FLT_RND_ERR0.5FLT_IEC_5591FLT_SUBNORMAL1FLT_TRUE_MIN1.40129846E-45DBL_IEC_5591DBL_SUBNORMAL1DBL_TRUE_MIN4.94065646E-324 ***7.x.2 MathematicsSeveral functions are declared to provide additional capability beyond<math.h>. Most synopses specify a function which takes one or moredoublearguments and returns adoublevalue; for each such function, there are functions with the same name but withfandlsuffixes which are corresponding functions withfloatandlong doublearguments and return values. ****7.x.2.1 Exponential and logarithmic functions*****7.x.2.1.1 The fracrep functionSynopsis#include <stdlia.h>double fracrep(double x);DescriptionThefracrepfunction extracts the fraction of the model representation ofx, as a signed normalized fraction in the format ofx.ReturnsThefracrepfunction returns the valuey, such thatyis adoublewith magnitude in the interval [1/FLT_RADIX, 1) or zero, andxequalsytimesFLT_RADIXraised to the power (logb(x)+1.0). The value returned for zero is 0.0. *****7.x.2.1.2 The ulp functionSynopsis#include <stdlia.h>double ulp(double x);DescriptionTheulpfunction computes the value of a Unit in the Last Place ofx. A domain error occurs if the argument is zero. A range error occurs if the magnitude ofxis too small and subnormals are not supported.ReturnsTheulpfunction returns the valueFLT_RADIXraised to the power (logb(x)+1-).ppis the precision of the floating type and is one of *_MANT_DIG. ****7.x.2.2 Sign function*****7.x.2.2.1 The fsgn functionSynopsis#include <stdlia.h>double fsgn(double x);DescriptionThefsgnfunction computes the sign of a floating-point numberx. Positive floating-point numbers have a sign of +1.0, negative floating-point numbers have a sign of -1.0, and zero has a sign of 0.0.ReturnsThefsgnfunction returns the sign. ****7.x.2.3 Manipulation functions*****7.x.2.3.1 The fsucc functionSynopsis#include <stdlia.h>double fsucc(double x);DescriptionThefsuccfunction determines the next representable value, in the type of the function, afterxin the direction of +infinity. A range error occurs ifxis the largest positive finite number.ReturnsThefsuccfunction returns the smallest representable value, of the same type, greater thanx. *****7.x.2.3.2 The fpred functionSynopsis#include <stdlia.h>double fpred(double x);DescriptionThefpredfunction determines the next representable value, in the type of the function, afterxin the direction of -infinity. A range error occurs ifxis the largest negative finite number.ReturnsThefpredfunction returns the largest representable value, of the same type, less thanx. *****7.x.2.3.3 The truncto functionSynopsis#include <stdlia.h>double truncto(double x, int n);DescriptionThetrunctofunction truncates (rounds toward zero)xtondigits of precision.ReturnsThetrunctofunction returns the value for normal numbers: sign(x) * floor(|x|/(FLT_RADIX**(expon(x)-n))) * FLT_RADIX**(expon(x)-n) and for subnormal numbers: sign(x) * floor(|x|/(FLT_RADIX**(emin-n))) * FLT_RADIX**(emin-n). Ifnis less than 1, returns 0. Ifnis greater than precision ofx, returnsx. *****7.x.2.3.4 The roundto functionSynopsis#include <stdlia.h>double roundto(double x, int n);DescriptionTheroundtofunction rounds (rounds to biased nearest with ties going away from zero)xtondigits of precision. A range error may occur.ReturnsTheroundtofunction returns the value for normal numbers: sign(x) * floor(|x|/(FLT_RADIX**(expon(x)-n))+0.5) * FLT_RADIX**(expon(x)-n) and for subnormal numbers: sign(x) * floor(|x|/(FLT_RADIX**(emin-n))+0.5) * FLT_RADIX**(emin-n). Ifnis less than 1, returns 0. Ifnis greater than precision ofx, returnsx. ****7.x.2.4 Conversion macrosThe following subclauses provide macros that convert from floating-point type to integral type using round to nearest rounding. The round to nearest can be biased (ties round away from zero) or unbiased (such as IEC 559 round to nearest even). In the synopses in this subclause, real-floating indicates that the argument must be an expression of real floating type. *****7.x.2.4.1 The icvt macroSynopsis#include <stdlia.h>int icvt(real-floating x);DescriptionTheicvtmacro rounds its argument to the nearest integral value. If the rounded value is outside the range ofint, the numeric result is unspecified. A range error may occur if the magnitude ofxis too large.ReturnsTheicvtmacro returns the rounded integral value. *****7.x.2.4.2 The lcvt macroSynopsis#include <stdlia.h>long lcvt(real-floating x);DescriptionThelcvtmacro is equivalent to theicvtmacro, except that the returned value has typelong. *****7.x.2.4.3 The llcvt macroSynopsis#include <stdlia.h>long long llcvt(real-floating x);DescriptionThellcvtmacro is equivalent to theicvtmacro, except that the returned value has typelong long. *****7.x.2.4.4 The uicvt macroSynopsis#include <stdlia.h>unsigned int uicvt(real-floating x);DescriptionTheuicvtmacro rounds its argument to the nearest integral value. If the rounded value is outside the range ofunsigned int, the rounded value is wrapped modulo (UINT_MAX+1).ReturnsTheuicvtmacro returns the rounded integral value. *****7.x.2.4.5 The ulcvt macroSynopsis#include <stdlia.h>unsigned long ulcvt(real-floating x);DescriptionTheulcvtmacro is equivalent to theuicvtmacro, except that the returned value has typeunsigned long. *****7.x.2.4.6 The ullcvt macroSynopsis#include <stdlia.h>unsigned long long ullcvt(real-floating x);DescriptionTheullcvtmacro is equivalent to theuicvtmacro, except that the returned value has typeunsigned long long. ***7.x.3 General utilitiesSeveral functions are declared to provide additional capability beyond<stdlib.h>. ****7.x.3.1 The sgn functionSynopsis#include <stdlia.h>int sgn(int j);DescriptionThesgnfunction computes the sign of an integerj. Positive integers have a sign of +1, negative integers have a sign of -1, and zero has a sign of 0.ReturnsThesgnfunction returns the sign. ****7.x.3.2 The lsgn functionSynopsis#include <stdlia.h>long int lsgn(long int j);DescriptionThelsgnfunction is similar to thesgnfunction, except that the argument and returned value each have typelong int. ****7.x.3.3 The llsgn functionSynopsis#include <stdlia.h>long long int llsgn(long long int j);DescriptionThellsgnfunction is similar to thesgnfunction, except that the argument and returned value each have typelong long int. ****7.x.3.4 The modulo functionSynopsis#include <stdlia.h>int modulo(int numer, int denom);DescriptionThemodulofunction computes the modulus, that is, [Ed: math equation]numer-(floor(numer/denom)*denom). Ifdenomis zero, the behavior is undefined.ReturnsThemodulofunction returns the modulus. ****7.x.3.5 The lmodulo functionSynopsis#include <stdlia.h>long int lmodulo(long int numer, long int denom);DescriptionThelmodulofunction is similar to themodulofunction, except that the arguments and returned value each have typelong int. ****7.x.3.6 The llmodulo functionSynopsis#include <stdlia.h>long long int llmodulo(long long int numer, long long int denom);DescriptionThellmodulofunction is similar to themodulofunction, except that the arguments and returned value each have typelong long int. ***7.x.4 NotificationEach macroINT_OVERFLOWINT_DIVBYZEROINT_INVALIDis defined if and only if the implementation supports the exception by means of the functions in 7.x.4.2. The defined macros expand to integral constant expressions whose values are distinct powers of 2. The macroINT_ALL_EXCEPTis simply the bitwise OR of all integer exception macros defined by the implementation. These next three macros describe what notifications happen for conversions of values from floating-point types to integral types for some specific values. -- value to indicate what notification happens for NaNs,FP2INT_OF_NANIt should be INT_INVALID, but may be FE_INVALID or another exception indicator macro. -- value to indicate what notification happens for infinities,FP2INT_OF_INFIt should be INT_INVALID, but may be FE_INVALID or another exception indicator macro. -- value to indicate what notification happens for out-of-bounds integral values,FP2INT_OF_LARGEIt should be INT_OVERFLOW, but may be FE_INVALID or another exception indicator macro, when INT_OUT_OF_BOUNDS is 2 (notify). The FP2INT_OF_LARGE macro shall be 0 (meaning no exception) when INT_OUT_OF_BOUNDS is 1 (wrap). The macroDISTINGUISH_INT_DIV_BY_ZEROhas a boolean value (0 or 1) to indicate if 0/0 can be distinguished from non-zero/zero. If this is true, then 0/0 will notify as invalid, else, as divbyzero. The macroDISTINGUISH_FP_DIV_BY_ZEROhas a boolean value (0 or 1) to indicate if 0.0/0.0 can be distinguished from finite non-zero/zero. If this is true, then 0.0/0.0 will notify as invalid, else, as divbyzero. ****7.x.4.1 The LIA_NOTIFY pragma and macro*****7.x.4.1.1 The LIA_NOTIFY pragmaSynopsis#include <stdlia.h>#pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP }DescriptionThe LIA_NOTIFY pragma provides a means to inform the implementation which notification mechanism is to be used[footnote]. The pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another LIA_NOTIFY pragma is encountered, or until the end of the translation unit. When inside a compound statement, the pragma takes effect from its occurrence until another LIA_NOTIFY pragma is encountered (within a nested compound statement), or until the end of the compound statement; at the end of a compound statement the state for the pragma is restored to its condition just before the compound statement. The effect of this pragma in any other context is undefined. If part of a program tests flags or runs under non-default mode settings, but was translated with the state for the LIA_NOTIFY pragma UNDEF, then the behavior of that program is undefined. UNDEF shall cause notifications to be undefined behaviour. This matches C89/C95. IGNORE shall cause notifications to be ignored. Traps shall not be taken. It is implementation defined if status flags will be set. An implementation defined continuation value will be used in place of the failing arithmetic operation. This causes the final check of the status flags at program termination to be suppressed. This allows the optimizations mentioned in the subsection on "FENV_ACCESS off" to be done. FLAGS shall cause notifications to set a status flag and proceed with a continuation value in place of the arithmetic failure. It is implementation defined if the final check of some status flags at program termination will be performed. TRAP shall cause notifications to trap. It is implementation defined if a trap shall be turned into a raise of some signal, or result in program termination. Until <stdlia.h> is included, the default state for the pragma shall be UNDEF. Once <stdlia.h> is included, the default state for the pragma is implementation-defined and shall be one of FLAGS, TRAP, (or DYNAMIC if supported). It is implementation defined if the different translation units that comprise a program are translated with different LIA_NOTIFY states. It is implementation defined which ofINT_OVERFLOW,INT_DIVBYZERO,INT_INVALID,FE_INEXACT,FE_UNDERFLOW,FE_OVERFLOW,FE_DIVBYZERO, andFE_INVALIDare defined. Those defined determine the set of notifications being checked. [footnote]Notification is the process by which a program is informed that an arithmetic operation cannot be performed. *****7.x.4.1.2 The LIA_NOTIFY macroThe macroLIA_NOTIFYhas one of these values (with corresponding meaning) 0 Undefined, like C89/C95 1 Notifications are ignored 2 All notifications will set flags 3 All notifications will trap 4 Program switches between flags and traps at runtime to indicate the current way notifications are being handled. That is, the macro tracks the state of the LIA_NOTIFY pragma. ****7.x.4.2 Exception flagsThe following functions provide access to the integer exception flags. They support the basic abstraction of flags that are either set or clear. Theintinput argument for the functions represents a subset of integer exceptions, and can be constructed by bitwise ORs of the integer exception macros, for example (INT_DIVBYZERO | INT_INVALID). For other argument values the behavior of these functions is undefined. *****7.x.4.2.1 The ieclearexcept functionSynopsis#include <stdlia.h>void ieclearexcept(int excepts);DescriptionThe ieclearexcept function clears the supported integer exceptions represented by its argument. *****7.x.4.2.2 The ieraiseexcept functionSynopsis#include <stdlia.h>void ieraiseexcept(int excepts);DescriptionThe ieraiseexcept function raises the supported integer exceptions represented by its argument. The order in which these exceptions are raised is unspecified. *****7.x.4.2.3 The ietestexcept functionSynopsis#include <stdlia.h>int ietestexcept(int excepts);DescriptionThe ietestexcept function determines which of a specified subset of the integer exception flags are currently set. Theexceptsargument specifies the integer exception flags to be queried.[footnote] [footnote]. This mechanism allows testing several exceptions with just one function call.ReturnsThe ietestexcept function returns the value of the bitwise OR of the integer exception macros corresponding to the currently set exceptions included inexcepts. * -- Add to 7.? Type-generic math <tgmath.h>: <stdlia.h> after all occurances of <math.h> ** -- Add to 7.?.1 Type-generic macros *** -- Add to the list of real (but not complex) functions that starts atan2, exp2:fracrepulpfsgnfsuccfpredtrunctoroundto* -- Add to Annex D Library summary ** -- Add new subclause:D.x Notification and additional utilities <stdlia.h>*** -- Add new subclause:D.x.1 Limits**** -- Add new subclause:D.x.1.1 Integral limitsINT_OUT_OF_BOUNDS**** -- Add new subclause:D.x.1.2 Floating-point limitsFLT_RND_ERRFLT_TRUE_MINDBL_TRUE_MINLDBL_TRUE_MINFLT_SUBNORMALDBL_SUBNORMALLDBL_SUBNORMALFLT_IEC_559DBL_IEC_559LDBL_IEC_559*** -- Add new subclause:D.x.2 Mathematics[Note to editor: If we need to include the float and long double versions, here, and in <math.h> and <complex.h>, please add them.]double fracrep(double x);double ulp(double x);double fsgn(double x);double fsucc(double x);double fpred(double x);double truncto(double x, int n);double roundto(double x, int n);*** -- Add new subclause:D.x.3 General utilitiesint icvt(real-floating x);long lcvt(real-floating x);long long llcvt(real-floating x);unsigned int uicvt(real-floating x);unsigned long ulcvt(real-floating x);unsigned long long ullcvt(real-floating x);int sgn(int j);long int lsgn(long int j);long long int llsgn(long long int j);int modulo(int numer, int denom);long int lmodulo(long int numer, long int denom);long long int llmodulo(long long int numer, long long int denom);*** -- Add new subclause:D.x.4 NotificationINT_OVERFLOWINT_DIVBYZEROINT_INVALIDINT_ALL_EXCEPTFP2INT_OF_NANFP2INT_OF_INFFP2INT_OF_LARGEDISTINGUISH_INT_DIV_BY_ZERODISTINGUISH_FP_DIV_BY_ZERO#pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP }LIA_NOTIFYvoid ieclearexcept(int excepts);void ieraiseexcept(int excepts);int ietestexcept(int excepts);* -- Add to Annex F IEC 559 Floating-Point Arithmetic: ** -- Add new subclause F.10 <stdlia.h>: *** F.10.1 Exponential and logarithmic functions **** F.10.1.1 The fracrep function fracrep(-0.0) returns -0.0 fracrep(+/-INFINITY) returns +/-INFINITY **** F.10.1.2 The ulp function ulp(-0.0) returns a NaN and raises the invalid exception. ulp(+/-INFINITY) returns a NaN and raises the invalid exception. ulp(1.0) returns DBL_EPSILON. *** F.10.2 Sign function **** F.10.2.1 The fsgn function fsgn(-0.0) returns -0.0 fsgn(+INFINITY) returns +1.0 fsgn(-INFINITY) returns -1.0 fsgn(NaN) returns the same NaN. *** F.10.3 Manipulation functions **** F.10.3.1 The fsucc function fsucc(-0.0) returns +DBL_TRUE_MIN fsucc(+INFINITY) returns +INFINITY fsucc(+DBL_MAX) returns +INFINITY and raises overflow. **** F.10.3.2 The fpred function fpred(-0.0) returns -DBL_TRUE_MIN fpred(-INFINITY) returns -INFINITY fpred(-DBL_MAX) returns -INFINITY and raises overflow. **** F.10.3.3 The truncto function truncto(-0.0, n) returns -0.0 for any n. truncto(+/-INFINITY, n) returns +/-INFINITY for any n. truncto(NaN, n) returns the same NaN for any n. **** F.10.3.4 The roundto function roundto(-0.0, n) returns -0.0 for any n. roundto(+/-INFINITY, n) returns +/-INFINITY for any n. roundto(NaN, n) returns the same NaN for any n. *** F.10.4 Conversion macros **** F.10.4.1 The icvt macro icvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. icvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF. **** F.10.4.2 The lcvt macro lcvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. lcvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF. **** F.10.4.3 The llcvt macro llcvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. llcvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF. **** F.10.4.4 The uicvt macro uicvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. uicvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF. **** F.10.4.5 The ulcvt macro ulcvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. ulcvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF. **** F.10.4.6 The ullcvt macro ullcvt(NaN) returns an unspecified value and raises FP2INT_OF_NAN. ullcvt(+/-INFINITY) returns an unspecified value and raises FP2INT_OF_INF.