From owner-freebsd-standards@FreeBSD.ORG Fri Oct 21 10:50:58 2005 Return-Path: X-Original-To: freebsd-standards@freebsd.org Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E79D516A41F for ; Fri, 21 Oct 2005 10:50:58 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1510243D45 for ; Fri, 21 Oct 2005 10:50:57 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87]) by mailout1.pacific.net.au (8.13.4/8.13.4/Debian-3) with ESMTP id j9LAouHk008223; Fri, 21 Oct 2005 20:50:56 +1000 Received: from epsplex.bde.org (katana.zip.com.au [61.8.7.246]) by mailproxy2.pacific.net.au (8.13.4/8.13.4/Debian-3) with ESMTP id j9LAoqDG014286; Fri, 21 Oct 2005 20:50:53 +1000 Date: Fri, 21 Oct 2005 20:50:53 +1000 (EST) From: Bruce Evans X-X-Sender: bde@epsplex.bde.org To: Steve Kargl In-Reply-To: <20051016184129.GA24651@troutmask.apl.washington.edu> Message-ID: <20051021194624.H598@epsplex.bde.org> References: <20051002191841.GA40568@troutmask.apl.washington.edu> <20051004164618.U47262@delplex.bde.org> <20051005032400.GA6736@troutmask.apl.washington.edu> <20051005191936.N51036@delplex.bde.org> <20051006212602.GA40609@troutmask.apl.washington.edu> <20051007231439.F58005@delplex.bde.org> <20051007190239.GA78674@troutmask.apl.washington.edu> <20051008052850.S59139@delplex.bde.org> <20051010185153.GA55589@troutmask.apl.washington.edu> <20051012160109.I73531@delplex.bde.org> <20051016184129.GA24651@troutmask.apl.washington.edu> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-standards@freebsd.org Subject: Re: complex.h math functions X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Oct 2005 10:50:59 -0000 On Sun, 16 Oct 2005, Steve Kargl wrote: > On Wed, Oct 12, 2005 at 05:23:28PM +1000, Bruce Evans wrote: > Hopefully, this new version is closer to KNF. It still has only 4 chars for all secondary indents >> use it. Listing all the special cases also serves as documentation. >> I think the current order of special cases is not quite the best, >> however. > > I don't follow why you think the special cases need to be re-order. > Without knowing how the user base will abuse ccosh, there should > be no prefered order. The current order is almost that in the standard. This order is not bad but it might not give the simplest or shortest classification. In particular, I think it might be better to group by 0's before grouping by Infs and NaNs. > This version incorporates your changes, fixes > a few more whitespace problems, and expands the > comments on the exceptional cases. I modified to to try to document all the sign combinations, and fixed a couple of bugs: % --- s_ccosh.c~ Mon Oct 17 12:11:18 2005 % +++ s_ccosh.c Tue Oct 18 18:11:22 2005 % @@ -63,9 +63,17 @@ % % /* % - * cosh(+0 + I Inf) = NaN +- I 0. The sign of 0 in the result % - * is unspecified. Raise the invalid floating-point exception. % + * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0. % + * The sign of 0 in the result is unspecified. Choice = normally % + * the same as dNaN. Raise the invalid floating-point exception. % * % - * cosh(+0 + I NaN) = NaN +- I 0. The sign of 0 in the result % - * is unspecified. % + * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0. % + * The sign of 0 in the result is unspecified. Choice = normally % + * the same as d(NaN). % + * % + * Say something about our sign choices generally but not specifically? % + * The above is specific; dNaN = default NaN and d(NaN) = input NaN % + * with default transformation under operations (e.g., on i386's, % + * convert signaling NaNs to quiet NaNs by setting the quiet bit). % + * XXX indentation of all of these. % */ % if ((ix | lx) == 0 && iy >= 0x7ff00000) This also says something about NaN not always being the same value. I'm not sure where this should be documented. Ther is another indentation problem in these comments. 2 spaces after the "*" is unusual, and is not useful since the same indentation is used for the formulas and the descriptions. I only changed the formatting to start a new line after the formulas. % @@ -73,9 +81,11 @@ % % /* % - * cosh(x + I Inf) = NaN + I NaN. Raise the invalid % + * cosh(x +- I Inf) = dNaN + I dNaN. % + * Raise the invalid % * floating-point exception for finite nonzero x. % * % - * cosh(x + I NaN) = NaN + I NaN. Optionally raise the invalid % - * floating-point exception for finite nonzero x. % + * cosh(x + I NaN) = d(NaN) + I d(NaN). % + * Optionally raises the invalid % + * floating-point exception for finite nonzero x. Choice = raise. % */ % if (ix < 0x7ff00000 && iy >= 0x7ff00000) An earlier version tried to document the sign of the resulting NaN. I decided that this was too much detail. But the detail that the sign of 0's is copied from the sign of a NaN is documented for other cases. This also improves the wording for options. % @@ -83,10 +93,13 @@ % % /* % - * cosh(+Inf + I 0) = +Inf + I 0. % - * cosh(+Inf + I NaN) = +Inf + I NaN. % - * cosh(+Inf + I y) = +Inf cis(y) for finite nonzero y. % - * cis(y) = cos(y) + I sin(y). % - * cosh(+Inf + I Inf) = +Inf + I NaN. The sign of Inf in the result % - * is unspecified. Raise the invalid floating-point exception. % + * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0. % + * % + * cosh(+-Inf + I NaN) = +Inf + I d(NaN). % + * % + * cosh(+-Inf +- I Inf) = +Inf + I dNaN. % + * The sign of Inf in the result is unspecified. Choice = always +. % + * Raise the invalid floating-point exception. % + * % + * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y) % */ % if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { This also adds newlines and drops cis(). cis() doesn't work in the precence of signs. % @@ -99,11 +112,14 @@ % % /* % - * cosh(NaN + I 0) = NaN +- I 0. The sign of 0 in the result % + * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0. % + * The sign of 0 in the result % * is unspecified. % * % - * cosh(NaN + I y) = NaN + I NaN. Raise the invalid % - * floating-point exception for finite nonzero y. % + * cosh(NaN + I y) = d(NaN) + I d(NaN). % + * Optionally raises the invalid % + * floating-point exception for finite or infinite nonzero y. % + * Choice = raise for infinite y only. % * % - * cosh(NaN + I NaN) = NaN + I NaN. % + * cosh(NaN + I NaN) = d(NaN) + I d(NaN). % */ % if ((iy | ly) == 0) This also fixes the description of the exception for cos(NaN + I y). I checked all your decriptions against n1124.pdf and got this fix from there. Note that the case cosh(NaN +- I Inf) is together with cosh(NaN + I y) for finite y since finite and infinite y's act the same here because the NaN dominates. Hmm, it seems wrong to even optionally raise an exception for finite y. > >> % diff -ruN /usr/src/lib/msun/man/cosh.3 freebsd/src/lib/msun/man/cosh.3 >> % --- /usr/src/lib/msun/man/cosh.3 Fri Jan 14 15:28:28 2005 >> % +++ freebsd/src/lib/msun/man/cosh.3 Sat Oct 8 11:46:29 2005 >> % ... >> >> OK; could be more detailed. > > Do you want a section that describes the range of inputs that > return a non-infinite results? Do you want a section that > describes the return value and the exceptional cases? I'll > have to do this later because I'll need to learning some > additional mdoc features. Exceptional cases are mostly not described at all for the real functions, so I wouldn't describe them better for the complex functions. I was thinking mainly of doumenting the intention that the error is < 2 ulps and noting cases where this isn't implemented in the BUGS section. >> % + * cosh(x + I Inf) = NaN + I NaN, finite x != 0, invalid exception. >> % + * cosh(x + I NaN) = NaN + I NaN, finite x != 0, opt. inval. except. >> % + */ >> >> Not quite enough space to describe it all on 1 line; the inputs and outputs >> get mixed cryptically; might use more formal abbreviations. > > I've expanded all comments to essentially the language in n1124.pdf. I'd still like to find a more concise version. Have a look at e_pow.c. > I've updated [c_coshf.c] also. Note, the forward declaration of > ccosh() is not needed because complex.h should contain a > prototype for it. My version with these and some other cosmetic changes. Everything except the copyright: % /* % * Hyperbolic cosine of a float complex argument. % */ % % #include % % float complex % ccoshf(float complex z) % { % % return (ccosh(z)); % } >> % diff -ruN /usr/src/lib/msun/src/math_private.h >> freebsd/src/lib/msun/src/math_private.h >> % --- /usr/src/lib/msun/src/math_private.h Fri Feb 4 12:05:39 2005 >> % +++ freebsd/src/lib/msun/src/math_private.h Fri Oct 7 17:30:40 2005 >> % @@ -155,6 +155,36 @@ >> % } while (0) >> % >> >> I needed a namespace hack to make this compile. Clients that don't use >> this shouldn't need to include , and this file shouldn't >> include it. I used "#ifdef I". > > A single letter #ifdef makes me nervous, and it isn't very descriptive. > I would suggest using #ifdef _COMPLEX_H. OTOH, math_private.h isn't > an installed header file, so only the person or persons writing the > complex math functions need to be bothered by this. I actually used `complex'. _COMPLEX_H is much better. The only problem with it is to misspell it consistently (it should be spelled _COMPLEX_H_; tail -1 *.h in /usr/include shows similar misspellings and other style bugs like backwards comments in about half of the headers). >> I think the underscores shouldn't be used here (not even for __inline). >> This is not a public interface so we don't need to be very careful with >> the namespace. > > I removed the underscores in my local tree. There, of course, were no problems. > >> Otherwise good. These interfaces seem to work well. > > You did not provide a patch to your local math_private.h. Here it is, after fixing the ifdef and removing most undercores: % Index: math_private.h % =================================================================== % RCS file: /home/ncvs/src/lib/msun/src/math_private.h,v % retrieving revision 1.17 % diff -u -2 -r1.17 math_private.h % --- math_private.h 4 Feb 2005 20:05:39 -0000 1.17 % +++ math_private.h 21 Oct 2005 10:43:22 -0000 % @@ -155,4 +162,45 @@ % } while (0) % % +#ifdef _COMPLEX_H % +/* % + * Inline functions that can be used to construct complex values. % + * % + * The C99 standard intends x+I*y to work for this, but x+I*y is % + * currently unusable in general since gcc introduces many overflow, % + * underflow, sign and efficiency bugs by rewriting I*y as (0+I)*(y+0*I) % + * and laboriously computing the full complex product. In particular, % + * I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted to 0+I*0. % + */ % +static __inline float complex % +cpackf(float x, float y) % +{ % + float complex z; % + % + __real__ z = x; % + __imag__ z = y; % + return (z); % +} % + % +static __inline double complex % +cpack(double x, double y) % +{ % + double complex z; % + % + __real__ z = x; % + __imag__ z = y; % + return (z); % +} % + % +static __inline long double complex % +cpackl(long double x, long double y) % +{ % + long double complex z; % + % + __real__ z = x; % + __imag__ z = y; % + return (z); % +} % +#endif /* _COMPLEX_H */ % + % /* % * ieee style elementary functions > BTW, the exceptional cases for ccos(z) are defined in n1124.pdf > in terms of ccos(z) = ccosh(I z). We can do > > double complex > ccos(double complex z) > { > return (ccosh(-cimag(z),creal(z)); > } > > or if you prefer we can copy s_ccosh.c and change > > x = creal(z); > y = cimag(z); > to > x = -cimag(z); > y = creal(x); Use the version with the extra function call for now. Bruce