This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Improve clog, clog10 handling of values with real or imaginarypart slightly above 1 (bug 13629)
- From: Allan McRae <allan at archlinux dot org>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Sat, 04 Aug 2012 09:13:21 +1000
- Subject: Re: Improve clog, clog10 handling of values with real or imaginarypart slightly above 1 (bug 13629)
- References: <Pine.LNX.4.64.1207302307130.13404@digraph.polyomino.org.uk>
On 31/07/12 09:10, Joseph S. Myers wrote:
> Continuing fixing the various cases of clog and clog10 near |z| = 1,
> this patch fixes cases where the larger of the real and imaginary
> parts has absolute value between 1 and 2, and the other is small (less
> than 1). In such cases, use of log(hypot) can result in large errors,
> but it is straightforward to get more accurate results using
> log1p((x-1)*(x+1)+y*y) (subject to avoiding underflow for y*y);
> precision extension techniques aren't needed in this case.
>
> To avoid the LDBL_EPSILON issue that arose for ctanl/ctanhl for
> ldbl-128ibm, I made the long double functions redefine LDBL_EPSILON in
> that case (there are other reasons ldbl-128ibm has its own versions of
> ctanl and ctanhl, but hopefully it can avoid needing its own versions
> of clogl / clog10l).
>
> Tested x86_64 and x86 and ulps updated accordingly. (Because of the
> use of clog in the implementation of various other functions, these
> changes perturbed the results of some tests for those other functions,
> resulting in new 1ulp errors for various tests. The cases where the
> inverse trig / hyperbolic functions end up using clog for values near
> |z| = 1 will eventually need fixing to call log1p directly, since no
> matter how accurate clog is there will still be large errors in the
> final result resulting from small errors in the argument to clog; the
> casinh case of this is bug 10357.)
>
> 2012-07-30 Joseph Myers <joseph@codesourcery.com>
>
> [BZ #13629]
> * math/s_clog.c (__clog): Use __log1p if larger part has absolute
> value between 1.0 and 2.0 and smaller part has absolute value less
> than 1.0.
> * math/s_clog10.c (__clog10): Likewise.
> * math/s_clog10f.c (__clog10f): Likewise.
> * math/s_clog10l.c (__clog10l): Likewise.
> * math/s_clogf.c (__clogf): Likewise.
> * math/s_clogl.c (__clogl): Likewise.
> * math/libm-test.inc (clog_test): Add more tests.
> (clog10_test): Likewise.
> * sysdeps/i386/fpu/libm-test-ulps: Update.
> * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
>
I have not formally checked, but I assume this patch is the reason I
started getting these errors on i686:
make[2]: *** [/build/src/glibc-build/math/test-ldouble.out] Error 1
make[2]: *** [/build/src/glibc-build/math/test-ildoubl.out] Error 1
test-ldouble.out:
testing long double (without inline functions)
Failure: Test: Real part of: clog10 (0x1.234566p-30 + 1.0 i) ==
2.438200411482400072282924063740535840474e-19 +
6.821881764607257184291586401763604544928e-1 i
Result:
is: 2.43820041148240007216e-19 0x8.fed0afa8a79dfe000000p-65
should be: 2.43820041148240007240e-19 0x8.fed0afa8a79dfe100000p-65
difference: 2.35098870164457501594e-38 0x8.00000000000000000000p-128
ulp : 1.0000
max.ulp : 0.0000
Test suite completed:
5195 test cases plus 4487 tests for exception flags executed.
1 errors occurred.
test-ildoubl.out
testing long double (inline functions)
Failure: Test: Real part of: clog10 (0x1.234566p-30 + 1.0 i) ==
2.438200411482400072282924063740535840474e-19 +
6.821881764607257184291586401763604544928e-1 i
Result:
is: 2.43820041148240007216e-19 0x8.fed0afa8a79dfe000000p-65
should be: 2.43820041148240007240e-19 0x8.fed0afa8a79dfe100000p-65
difference: 2.35098870164457501594e-38 0x8.00000000000000000000p-128
ulp : 1.0000
max.ulp : 0.0000
Test suite completed:
5132 test cases plus 4424 tests for exception flags executed.
1 errors occurred.