This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [BZ #15335] Don't use hard-coded qNaN values in sysdeps/ieee754/dbl-64/e_pow.c:__ieee754_pow
- From: Andreas Jaeger <aj at suse dot com>
- To: libc-alpha at sourceware dot org
- Date: Thu, 04 Apr 2013 09:38:58 +0200
- Subject: Re: [BZ #15335] Don't use hard-coded qNaN values in sysdeps/ieee754/dbl-64/e_pow.c:__ieee754_pow
- References: <87fvz7z91m dot fsf at schwinge dot name> <87d2ubz8j0 dot fsf at schwinge dot name>
On Wednesday, April 03, 2013 22:03:31 Thomas Schwinge wrote:
> Hi!
>
> On Wed, 03 Apr 2013 21:52:21 +0200, I wrote:
> > * sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Remove
> > unreachable code.
>
> On top of that, OK to commit?
>
> [BZ #15335]
> * sysdeps/ieee754/dbl-64/upow.h (NaNQ): Remove definitions.
> * sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Instead, use
> input NaN values or generate a qNaN by arithmetic operation.
>
> diff --git NEWS NEWS
> index 3bb5cb3..1697d4e 100644
> --- NEWS
> +++ NEWS
> @@ -12,7 +12,7 @@ Version 2.18
> 10357, 11120, 11561, 12723, 13550, 13889, 13951, 14142, 14176,
> 14200, 14317, 14327, 14496, 14812, 14920, 14964, 14981, 14982, 14985,
> 14994, 14996, 15003, 15006, 15020, 15023, 15036, 15054, 15055, 15062,
> 15078, - 15160, 15214, 15232, 15234, 15283, 15285, 15287, 15304,
> 15307. + 15160, 15214, 15232, 15234, 15283, 15285, 15287, 15304,
> 15307, 15335.
>
> * Add support for calling C++11 thread_local object destructors on
> thread and program exit. This needs compiler support for offloading
> C++11 diff --git sysdeps/ieee754/dbl-64/e_pow.c
> sysdeps/ieee754/dbl-64/e_pow.c index 44d6f62..9a766e7 100644
> --- sysdeps/ieee754/dbl-64/e_pow.c
> +++ sysdeps/ieee754/dbl-64/e_pow.c
> @@ -71,8 +71,9 @@ __ieee754_pow(double x, double y) {
> u.x=x;
> if (v.i[LOW_HALF] == 0) { /* of y */
> qx = u.i[HIGH_HALF]&0x7fffffff;
> - /* Checking if x is not too small to compute */
> - if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000))
> return NaNQ.x; + /* Is x a NaN? */
> + if (((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx >
> 0x7ff00000)) + return x;
> if (y == 1.0) return x;
> if (y == 2.0) return x*x;
> if (y == -1.0) return 1.0/x;
> @@ -111,7 +112,7 @@ __ieee754_pow(double x, double y) {
>
> if (x == 0) {
> if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF]
> != 0) - || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)
> + || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000) /* NaN */
> return y;
> if (ABS(y) > 1.0e20) return (y>0)?0:1.0/0.0;
> k = checkint(y);
> @@ -124,9 +125,10 @@ __ieee754_pow(double x, double y) {
> qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
> qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */
>
> - if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0))
> return NaNQ.x; - if (qy >= 0x7ff00000 && (qy > 0x7ff00000 ||
> v.i[LOW_HALF] != 0)) - return x == 1.0 ? 1.0 : NaNQ.x;
> + if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) /*
> NaN */ + return x;
> + if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0)) /*
> NaN */ + return x == 1.0 ? 1.0 : y;
>
> /* if x<0 */
> if (u.i[HIGH_HALF] < 0) {
> @@ -139,7 +141,7 @@ __ieee754_pow(double x, double y) {
> }
> else if (qx == 0x7ff00000)
> return y < 0 ? 0.0 : INF.x;
> - return NaNQ.x; /* y not integer
> and x<0 */ + return (x - x) / (x - x); /* y
I'm not convinced of this change, the rest is fine.
The above raises an invalid exception - but the previous code did not.
Why is this change still fine?
Andreas
--
Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126