This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: PowerPC floating point little-endian [4 of 15]
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: Alan Modra <amodra at gmail dot com>
- Cc: <libc-alpha at sourceware dot org>
- Date: Wed, 10 Jul 2013 17:26:49 +0000
- Subject: Re: PowerPC floating point little-endian [4 of 15]
- References: <20130710012435 dot GN2602 at bubble dot grove dot modra dot org> <20130710012622 dot GQ2602 at bubble dot grove dot modra dot org>
On Wed, 10 Jul 2013, Alan Modra wrote:
> Another batch of ieee854 macros and union replacement. These four
> files also have bugs fixed with this patch. The fact that the two
> doubles in an IBM long double may have different signs means that
> negation and absolute value operations can't just twiddle one sign bit
> as you can with ieee864 style extended double. fmodl, remainderl,
> erfl and erfcl all had errors of this type. erfl also returned +1 for
> large magnitude negative input where it should return -1. The hypotl
> error is innocuous since the value adjusted twice is only used as a
> flag.
When fixing user-visible bugs, please file them in Bugzilla, and if
possible include testcases for them (that fail before, pass after the
patch) in libm-test.inc.
My guess is that fmod/remainder tests would be conditional on "#if defined
TEST_LDOUBLE && LDBL_MANT_DIG >= 106"; I'm less sure about erf/erfc, but
presumably by knowing where the error is, you should be able to make the
incorrect negation give errors of up to around 2^52 ulps, and cases with
large errors make suitable testcases. The erf issue with large negative
input is certainly easy to test - libm-test.inc is currently lacking any
coverage of finite negative values.
> if(__builtin_expect(hx<=hy,0)) {
> - if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
> + if (hx < hy
> + || (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy))
> + return x; /* |x|<|y| return x */
> if(lx==ly)
> - return Zero[(u_int64_t)sx>>63]; /* |x|=|y| return x*0*/
> + return Zero[(uint64_t)sx>>63]; /* |x|=|y| return x*0*/
It looks to me like the (lx==ly) conditional needs to check (lx^sx) and
(ly^sy) instead to be correct, further illustrating the value of a range
of new testcases.
--
Joseph S. Myers
joseph@codesourcery.com