Document WG14 N943 Date: Friday, November 24, 2000 8:12 PM I was asked by the Austin Common Standards Revision Group (http://www.opengroup.org/austin/) to clean up their man pages for the math library functions taking into account C99. After spending several days and making multiple passes thru C99 7.12 and Annex F and considering the comments from the other reviewers, I noticed a few items that I believe need to be fixed in C99. Possible Defect Reports related to the C99 math library. 1. fma(): Needs to mention possible overflow and underflow errors. 7.12.13.1 fma: Add to Description: A range error may occur. 2. nexttoward(): To make it clearer (required by 7.12.11.4), F.9.8.4 nexttoward: should be changed to: No additional requirements beyond nextafter. Also, that paragraph should be numbered. 3. lrint, llrint, lround, llround, ilogb: Need to be consistent (and explicit) when results are too big to represent in an integer type. Also, that case should be treated as a domain error. 7.12.6.5 ilogb: Change: A range error may occur if x is 0. to A domain error occurs if x is 0, infinite, or NaN. Add: If the correct value is outside the range of the return type, the numeric result is unspecifed, and a domain error occurs. 7.12.9.5 lrint/llrint: Change If the rounded value is outside the range of the return type, the numeric result is unspecifed. A range error may occur if the magnitude of x is too large. to If the rounded value is outside the range of the return type, the numeric result is unspecifed, and a domain error occurs. 7.12.9.7 lround/llround: Change If the rounded value is outside the range of the return type, the numeric result is unspecifed. A range error may occur if the magnitude of x is too large' to If the rounded value is outside the range of the return type, the numeric result is unspecifed, and a domain error occurs. 4. pow(0,<0) should be considered a pole error (result is an exact infinity) in the base standard (it already is in Annex F). 7.12.7.4 pow: Split: A domain error may occur if x is zero and y is less than or equal to zero. into A domain error may occur if x is zero and y is zero. and A range error may occur if x is zero and y is less than zero. 5. logb(0) should be considered a pole error in the base standard (it already is in Annex F). 7.12.6.11 logb: Change: A domain error may occur if the argument is zero. to A range error may occur if the argument is zero. 6. fmod(), remainder(), and remquo(): As one takes the limit as y approaches zero, the remainder approaches zero (0 <= |result| < |y|) and the quotient is unspecified. This series of changes may also require that IEEE-754 be changed. Assuming that fmod, remainder, and remquo should be consistent with each other, the following needs to be done. An alternative is to do some of these changes. 7.12.10.1 fmod: No change needed. 7.12.10.2 remainder: Add: If y is zero, whether a domain error occurs or the remainder functions return zero is implementation defined. 7.12.10.3 remquo: Add: If y is zero, the quotient stored is unspecified. F.9.7.1 fmod: Change fmod(x,y) returns a NaN and raises the "invalid" floating-point exception for x infinite or y zero. to two items: fmod(x,y) returns a NaN and raises the "invalid" floating-point exception for x infinite. and fmod(x,y) returns a zero (with sign of x) for y zero. F.9.7.2 remainder: Add: remainder(x,y) returns a zero (with sign of x) for y zero. F.9.7.3 remquo: Add: remquo(x,y) returns a zero (with sign of x) for y zero and has an unspecified quotient stored. Also add, When remquo returns a NaN, the quotient stored is unspecified. 7. tgamma(zero or negative integer) should be considered a pole error since the correct mathematical result is an exact infinity (whose sign depends upon the direction that the limit is taken from). Annex F already does this for the zero argument case. 7.12.8.4 tgamma: Change: A domain error occurs if x is a negative integer or if the result cannot be represented when x is zero. to A range error may occur if x is a negative integer or zero. F.9.5.4 tgamma: Change: tgamma(x) returns a NaN and raises the "invalid" floating-point exception for x a negative integer. to tgamma(x) returns +INF and raises the "divide-by-zero" floating-point exception for x a negative integer. Change: tgamma(-INF) returns a NaN and raises the "invalid" floating-point exception. to tgamma(-INF) returns +INF and raises the "divide-by-zero" floating-point exception. ================================================================ The following is a brief summary of the error cases in the math libarary functions. It covers both the base standard (section 7.12) and the IEEE-754 annex F. Look for '@@' in the following to find the existing inconsistent error cases. The format of these lines is: function(arguments) base-error; Annex-F-error Domain error These should be a required domain error and raise invalid for Annex F. acos(not in [-1,+1]); invalid if Annex F asin(not in [-1,+1]); invalid if Annex F atan2(0,0) = may domain; no invalid if Annex F cos(INF) invalid if Annex F sin(INF) invalid if Annex F tan(INF) invalid if Annex F acosh(<1); invalid if Annex F atanh(not in [-1,+1]); invalid if Annex F log(<0); invalid if Annex F log10(<0); invalid if Annex F log1p(<-1); invalid if Annex F log2(<0); invalid if Annex F pow(finite negative,finite non-integer); invalid if Annex F pow(0,0) = may domain; no invalid if Annex F sqrt(<0); invalid if Annex F @@ fmod(x,0) = 0 or may domain; invalid if Annex F fmod(INF,y); invalid if Annex F @@ remainder(x,0); invalid if Annex F remainder(INF,y); invalid if Annex F @@ remquo(x,0); invalid if Annex F remquo(INF,y); invalid if Annex F @@ ilogb(0) = may range @@ lrint, llrint(for large args) = may range; invalid if Annex F @@ lrint, llrint(NaN or INF); invalid if Annex F @@ lround, llround(for large args) = may range; invalid if Annex F @@ lround, llround(NaN or INF); invalid if Annex F fma(x*y is invalid, z is NaN); optional invalid if Annex F fma(x*y+z is invalid); invalid if Annex F Pole (or singularity) error - one kind of range error These should be an optional range error and raise div-by-0 for Annex F. atanh(+/-1) = may range; div-by-0 if Annex F log(0) = may range; div-by-0 if Annex F log10(0) = may range; div-by-0 if Annex F log1p(-1) = may range; div-by-0 if Annex F log2(0) = may range; div-by-0 if Annex F @@ logb(0) = may domain; div-by-0 if Annex F @@ pow(0,<0) = may domain; div-by-0 if Annex F lgamma(0 or negative int) = may range; div-by-0 if Annex F @@ tgamma(0) = domain if result is not inf; div-by-0 if Annex F @@ tgamma(negative int) = domain; invalid if Annex F @@ tgamma(-INF) = domain; invalid if Annex F Overflow error - one kind of range error These should be a range error and raise overflow for Annex F. cosh(large args) sinh(large args) exp(large args) exp2(large args) expm1(large args) ldexp() = may scalbn, scalbln() = may hypot() = may pow() = may lgamma(large args) tgamma(large & small args) nextafter() result too large = may; overflow if Annex F nexttoward() result too large = may; overflow if Annex F fdim() = may @@ fma() = no errors mentioned Underflow error - one kind of range error These should be a range error and optional raise underflow for Annex F. exp(large args) exp2(large args) ldexp() = may scalbn, scalbln() = may hypot() = may pow() = may erfc(large args) fdim() = may nextafter() result too small; underflow if Annex F nexttoward() result too small; underflow if Annex F @@ fma() = no errors mentioned