From owner-freebsd-numerics@FreeBSD.ORG Tue May 28 10:48:11 2013 Return-Path: Delivered-To: freebsd-numerics@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 5845182D; Tue, 28 May 2013 10:48:11 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail04.syd.optusnet.com.au (mail04.syd.optusnet.com.au [211.29.132.185]) by mx1.freebsd.org (Postfix) with ESMTP id B88B6D27; Tue, 28 May 2013 10:48:10 +0000 (UTC) Received: from c122-106-156-23.carlnfd1.nsw.optusnet.com.au (c122-106-156-23.carlnfd1.nsw.optusnet.com.au [122.106.156.23]) by mail04.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id r4SAlj87005958 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 28 May 2013 20:47:56 +1000 Date: Tue, 28 May 2013 20:47:45 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: David Schultz Subject: Re: Use of C99 extra long double math functions after r236148 In-Reply-To: <20130528081212.GA13594@zim.MIT.EDU> Message-ID: <20130528195733.Q2294@besplex.bde.org> References: <501204AD.30605@missouri.edu> <20120727032611.GB25690@server.rulingia.com> <20120728125824.GA26553@server.rulingia.com> <501460BB.30806@missouri.edu> <20120728231300.GA20741@server.rulingia.com> <50148F02.4020104@missouri.edu> <20120729222706.GA29048@server.rulingia.com> <5015BB9F.90807@missouri.edu> <20130528043205.GA3282@zim.MIT.EDU> <20130528150808.F1298@besplex.bde.org> <20130528081212.GA13594@zim.MIT.EDU> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.0 cv=BPvrNysG c=1 sm=1 a=O6A2dy7pM2IA:10 a=kj9zAlcOel0A:10 a=PO7r1zJSAAAA:8 a=JzwRw_2MAAAA:8 a=Zc3-fPm5GV4A:10 a=hG9Faytz-pyrK-G3USYA:9 a=CjuIK1q_8ugA:10 a=QPu_LqNFptFJU9lF:21 a=io-CCv-q2jcpwO-C:21 a=ebeQFi2P/qHVC0Yw9JDJ4g==:117 X-Mailman-Approved-At: Tue, 28 May 2013 11:41:08 +0000 Cc: Diane Bruce , Bruce Evans , John Baldwin , David Chisnall , Stephen Montgomery-Smith , freebsd-numerics@FreeBSD.org, Steve Kargl , Peter Jeremy , Warner Losh X-BeenThere: freebsd-numerics@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussions of high quality implementation of libm functions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 May 2013 10:48:11 -0000 On Tue, 28 May 2013, David Schultz wrote: > On Tue, May 28, 2013, Bruce Evans wrote: >> @ diff -u2 catrigl.c~ catrigl.c >> @ --- catrigl.c~ 2012-09-22 21:14:24.000000000 +0000 >> @ +++ catrigl.c 2013-05-26 08:46:10.423187000 +0000 >> @ @@ -50,4 +50,6 @@ >> @ #define signbit(x) (__builtin_signbitl(x)) >> @ >> @ +long double atanhl(long double); >> @ + >> @ static const long double >> @ A_crossover = 10, >> >> catrigl.c depends on atanhl(), logl() and log1pl() existing. > > Yep, I'm ignoring the complex long double functions until the real > long double functions are done. I'm hoping that won't be too long! As usual, you can find my current versions in ~bde/msun/src/zztest/s_log*.c, ~bde/msun/src/zztest/ld128/s_logl.c, and ~bde/msun/src/zztest/cplex.c (clog*). Lots of macros in ~bde/msun/src/zztest/math_private.h are also needed. The header needs more cleaning than the C files, but you can easily extract the parts needed. >> % Index: tools/regression/lib/msun/test-invctrig.c >> % =================================================================== >> % --- tools/regression/lib/msun/test-invctrig.c (revision 0) >> % +++ tools/regression/lib/msun/test-invctrig.c (working copy) >> % @@ -0,0 +1,467 @@ >> % .... > >> % + * XXX gcc implements complex multiplication incorrectly. In >> % + * particular, it implements it as if the CX_LIMITED_RANGE pragma >> % + * were ON. Consequently, we need this function to form numbers >> % + * such as x + INFINITY * I, since gcc evalutes INFINITY * I as >> % + * NaN + INFINITY * I. >> % + */ >> % +static inline long double complex >> % +cpackl(long double x, long double y) >> % +{ >> % + long double complex z; >> % + >> % + __real__ z = x; >> % + __imag__ z = y; >> % + return (z); >> % +} >> >> Why duplicate this? I guess it is because math_private,h is hard to >> include. I use complicated conditionals (mostly switches on >> $(uname -p) and $(hostname) in shell scripts to locate it when >> compiling from external directories. > > I will change to CMPLXL, now that CMPLXL has been committed. > Thanks for reminding me. That won't be very portable. I already need ifdefs and extra code in math_private.h to restore the old version that works with old versions of gcc. > The ability to use complex numbers in > initializers is nice (ignore whitespace munging due to cut/paste): > > static const struct { > complex long double z; > complex long double acos_z; > complex long double asin_z; > complex long double atan_z; > } tests[] = { > { CMPLXL(0.75L, 0.25L), > CMPLXL(pi / 4, -0.34657359027997265470861606072908828L), > CMPLXL(pi / 4, 0.34657359027997265470861606072908828L), > CMPLXL(0.66290883183401623252961960521423782L, > 0.15899719167999917436476103600701878L) }, > }; I think you mean "nasty" :-). Simply x + I * y seems to work correctly with the following compilers on amd64: gcc-2.95.4, gcc-3.3.3, gcc-3.4.6, gcc-4.2.1, clang 3.3. But you cannot use either x + I * y or CMPLXL() with literals for for for long doubles, since on i386 most of the gcc's will round the long doubles to 53 bits, so you must use LD80C() for most long double constants, and LD80C() won't work inside either x + I * y or CMPLXL(). I didn't test this with exactly the above. Untested conversion of it: { 0.75L + I * 0.25L, pi / 4 + I * -0.34657359027997265470861606072908828L, pi / 4 + I * 0.34657359027997265470861606072908828L, 0.66290883183401623252961960521423782L + I * 0.15899719167999917436476103600701878L, }, Is pi a variable, and/or does CMPLXL() work with variables in static initializers? Non-static initializers and CMPLXL() can be used on variables constructed using LD80C(). Now gcc-3.3.3 generates horrible code for a runtime evaluation and probably causes overflow bugs for exceptional args (the ones that we invented cpack*() to avoid). gcc-4.2.1 generates good code. The freebsd cluster seems to have crashed while I was writing this, so I don't have access to the other compilers. >> The tests seem to be compiled with -O0. That tests a different >> environment than the usual runtime one, and in particular misses seeing >> most precision bugs. I mostly test with -O (-O2 with gcc is slower >> and even harder to debug, while with clang it makes little difference), >> but switch to -O0 to debug. -g -O is now almost unusable because -O >> optimizes away dead variables and -g is broken in many cases (sometimes >> it can't even show live variables). > > I want the tests to come as close as possible to testing the > behavior that real programs will see. Unfortunately, any test that > exercises different rounding modes or looks at floating-point > exceptions is pretty much doomed to fail with gcc and clang, so I > gave up. (Sometimes I wonder if there's any point in having a free > library that supports them if you need a commercial compiler to > take advantage.) However, the tests do sometimes uncover compiler > bugs that get fixed. They caught a few bugs in gcc builtins, and > an arithmetic bug in clang's constant-folding code, all of which > were fixed. But doesn't using -O0 give the opposite of that? The library is closer to working than tests and real programs since it is relatively careful and the compiler problems usually don't have much effect (since wrong rounding by the compiler tends to show up as errors of >= 1 ulp and gets fixed). Bruce