From owner-svn-src-all@FreeBSD.ORG Mon Nov 15 15:57:15 2010 Return-Path: Delivered-To: svn-src-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D71141065673; Mon, 15 Nov 2010 15:57:15 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail02.syd.optusnet.com.au (mail02.syd.optusnet.com.au [211.29.132.183]) by mx1.freebsd.org (Postfix) with ESMTP id 705F38FC20; Mon, 15 Nov 2010 15:57:14 +0000 (UTC) Received: from c122-106-146-145.carlnfd1.nsw.optusnet.com.au (c122-106-146-145.carlnfd1.nsw.optusnet.com.au [122.106.146.145]) by mail02.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id oAFFvB0F023999 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 16 Nov 2010 02:57:13 +1100 Date: Tue, 16 Nov 2010 02:57:11 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Alexander Best In-Reply-To: <20101113125648.GA25183@freebsd.org> Message-ID: <20101116011754.T1430@besplex.bde.org> References: <201011131054.oADAsA7I045096@svn.freebsd.org> <20101113125648.GA25183@freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Ulrich Spoerlein Subject: Re: svn commit: r215237 - head/lib/msun/src X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Nov 2010 15:57:16 -0000 On Sat, 13 Nov 2010, Alexander Best wrote: > thank you very much for fixing this long outstanding issue. > you might want to have a look at [1], where two more issues have been reported. > > [1] http://mailman.oakapple.net/pipermail/numeric-interest/2010-September/thread.html These are either features or not our problem (yet?). The second issue is compiler bugs, mostly for VC++. For gcc, the corresponding bugs are that gcc is not a C99 compiler, so it doesn't support fenv. clang has even worse support for fenv (both have no direct support for fenv, but clang does more optimizations that are invalid if the environment is not the default). fdlibm's problems in this area are that it was written before fenv existed, so it just assumes that the compiler doesn't do too many optimizations -- an assumption that is almost but not quite satisifed with gcc <= 4.2.1 (unless you enable bugs like -ffast-math of course). The other issue is a (historical?) bug now standardized by C99: from n1256.pdf: % -- pow(-Inf, y) returns +0 for y<0 and not an odd integer. % -- pow(-Inf, y) returns +Inf for y>0 and not an odd integer. So pow(-Inf, 0.5) must return +Inf and pow(-Inf, -0.5) must return +0, although the bug reporter wants the value to be NaN in both cases, like it would be for sqrt(-Inf) and 1/sqrt(-Inf), respectively. pow(-Inf, -0.5) = +0 is reasonable, since it can be interpreted as either 1/sqrt(-Inf) or sqrt(1/-Inf) = sqrt(-0) = 0, and the latter is reasonable and Standard (sqrt(-0) could be required to be NaN since -0 can be regarded as being on the branch cut for sqrt(), but that would make -0 too special, especially for real sqrt()). pow(-Inf, 0.5) = +Inf is not so reasonable, but is consistent with other (historical?) and now Standard bugs in pow(): essentially, everywhere that there is a correct special case for the second arg being an odd integer (so that there is no branch cut involved, and the oddness affects the sign of the result in the natural way), there is a bogus special case when the second arg is finite and not an odd integer, and another bogus special case when the second arge is infinite. The finite non-odd-integer cases are generally treated by throwing away all signs so that the result is +Inf or +0 where it would be +-Inf or +-0 for an odd integer. Infinite args are sort of both even and odd, so they should give all of the results +-Inf or +-0, but this is impossible so the result should be NaN, but Standards say that it is just +Inf or +0, as results from ignoring the odd integer singularities. >From n1156.pdf (not quoting the complementatry odd integer cases): % -- pow(+-0, y) returns +Inf and raises the divide-by-zero % exception for y<0 and not an odd integer. This is uncontroversial for +0. However, for -0, it must be interpreted as 1/pow(-0, -y) and not as 1/pow(1/-0, y) = 1/(-Inf, y) to avoid a controversial operation on -Inf. % -- pow(+-0, y) returns +0 for y>0 and not an odd integer. Uncontroversial for +0, and less controversial than the above for -0. % -- pow(-1, +-Inf) returns 1. Indirectly related. This is a new bug in n1156.pdf. It wasn't in n869 (not sure if it was in initial-C99), and isn't in fdlibm. but this is needed for bug for bug compatibility with pow(-1-eps, +-Inf). The value of the latter should be NaN, since pow(-1-eps, y) has limits both +-Inf as y -> +-Inf (strictly the latter should be NaN unless y is an integer, since a correct complex result is unrepresentable), but it is +Inf. But since we fix the sign for the latter, we should fix the sign for this too. % -- pow(x, -Inf) returns +Inf for |x|<1. % -- pow(x, -Inf) returns +0 for |x|>1. % -- pow(x, +Inf) returns +0 for |x|<1. % -- pow(x, +Inf) returns +Inf for |x|>1. Historical(?) and Standard, but bogus for x < -1 since pow() should only be defined there when y is an integer and then the result approaches both +-Inf. Less bogus for -1 < x <= 0 since then the result (although it should never be defined :-)) approaches +-0. % -- pow(-Inf, y) returns +0 for y<0 and not an odd integer. % -- pow(-Inf, y) returns +Inf for y>0 and not an odd integer. These 2 were quoted earlier. They are just the rules for +-0 inverted. cpow() has to deal with pow(x, y) actually existing for negative x, so it should use projective infinity and not have special cases for +-Inf or +-0, but presumably it has to be bug for bug compatible with pow() on the real axis so its special cases can only be more complicated and/or bogus. I checked most cases specified in n1156.pdf and found only the following non-conforming behaviour in FreeBSD: %C99 rule -- pow(-Inf, y) returns -0 for y an odd integer < 0. %fdlibm rule(?) * 17. -INF ** (anything) = -0 ** (-anything) fdlibm error: returns +0 instead of -0. I'm not sure if I matched the rules correctly. %C99 rule -- pow(-1, +-Inf) returns 1. %fdlibm rule * 9. +-1 ** +-INF is NAN fdlibm non-error: pow(-1, +-Inf) is NaN, not 1 as specified by C99. fdlibm non-error: pow(1, +-Inf) is 1 as specified by C99, not NaN as claimed in the comment. I know of 1 other similar bug in C99: lgamma(-Inf) should be NaN, but is Inf. lgamma() has a very bad singularity at -Inf even when it is restricted to the real axis. This bug is missing for tgamma(). Bruce