diff options
author | 2013-08-02 20:23:28 +0000 | |
---|---|---|
committer | 2013-08-02 20:23:28 +0000 | |
commit | d205ab02eabefec09df68de8ff35e0519ffc9a86 (patch) | |
tree | bd1af2e134d4ae75481b006c069142022a9a87d2 | |
parent | No longer needed since miod taught elf to mkuboot. (diff) | |
download | wireguard-openbsd-d205ab02eabefec09df68de8ff35e0519ffc9a86.tar.xz wireguard-openbsd-d205ab02eabefec09df68de8ff35e0519ffc9a86.zip |
Fix a couple of corner cases in the implementation of pow(3) to make it
compatible with C99. Most notably:
- 1**y == 1, even if y is NaN
- (-1)**+-Inf == 1
and adjust the cephes testsuite to test for the right thing here.
ok martynas@
-rw-r--r-- | lib/libm/src/e_pow.c | 9 | ||||
-rw-r--r-- | lib/libm/src/e_powf.c | 5 | ||||
-rw-r--r-- | lib/libm/src/ld80/e_powl.c | 10 | ||||
-rw-r--r-- | regress/lib/libm/cephes/testvect.c | 12 | ||||
-rw-r--r-- | regress/lib/libm/cephes/testvectl.c | 12 | ||||
-rw-r--r-- | regress/lib/libm/cephes/testvectll.c | 12 |
6 files changed, 33 insertions, 27 deletions
diff --git a/lib/libm/src/e_pow.c b/lib/libm/src/e_pow.c index 5fce17c8c7b..2af0e921b3e 100644 --- a/lib/libm/src/e_pow.c +++ b/lib/libm/src/e_pow.c @@ -24,13 +24,13 @@ * Special cases: * 1. (anything) ** 0 is 1 * 2. (anything) ** 1 is itself - * 3. (anything) ** NAN is NAN + * 3. (anything except 1) ** NAN is NAN * 4. NAN ** (anything except 0) is NAN * 5. +-(|x| > 1) ** +INF is +INF * 6. +-(|x| > 1) ** -INF is +0 * 7. +-(|x| < 1) ** +INF is +0 * 8. +-(|x| < 1) ** -INF is +INF - * 9. +-1 ** +-INF is NAN + * 9. +-1 ** +-INF is 1 * 10. +0 ** (+anything except 0, NAN) is +0 * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 * 12. +0 ** (-anything except 0, NAN) is +INF @@ -109,6 +109,9 @@ pow(double x, double y) /* y==zero: x**0 = 1 */ if((iy|ly)==0) return one; + /* x==1: 1**y = 1, even if y is NaN */ + if (hx==0x3ff00000 && lx == 0) return one; + /* +-NaN return x+y */ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) @@ -138,7 +141,7 @@ pow(double x, double y) if(ly==0) { if (iy==0x7ff00000) { /* y is +-inf */ if(((ix-0x3ff00000)|lx)==0) - return y - y; /* inf**+-1 is NaN */ + return one; /* (-1)**+-inf is 1 */ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ diff --git a/lib/libm/src/e_powf.c b/lib/libm/src/e_powf.c index d6e52d8b99b..3c4269d7146 100644 --- a/lib/libm/src/e_powf.c +++ b/lib/libm/src/e_powf.c @@ -64,6 +64,9 @@ powf(float x, float y) /* y==zero: x**0 = 1 */ if(iy==0) return one; + /* x==1: 1**y = 1, even if y is NaN */ + if (hx==0x3f800000) return one; + /* +-NaN return x+y */ if(ix > 0x7f800000 || iy > 0x7f800000) @@ -87,7 +90,7 @@ powf(float x, float y) /* special value of y */ if (iy==0x7f800000) { /* y is +-inf */ if (ix==0x3f800000) - return y - y; /* inf**+-1 is NaN */ + return one; /* (-1)**+-inf is NaN */ else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ diff --git a/lib/libm/src/ld80/e_powl.c b/lib/libm/src/ld80/e_powl.c index d05de530531..f72dd8d68b8 100644 --- a/lib/libm/src/ld80/e_powl.c +++ b/lib/libm/src/ld80/e_powl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_powl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ +/* $OpenBSD: e_powl.c,v 1.4 2013/08/02 20:23:28 kettenis Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> @@ -211,6 +211,9 @@ long e; if( y == 0.0L ) return( 1.0L ); +if( x == 1.0L ) + return( 1.0L ); + if( isnan(x) ) return( x ); if( isnan(y) ) @@ -219,10 +222,7 @@ if( isnan(y) ) if( y == 1.0L ) return( x ); -if( !isfinite(y) && (x == -1.0L || x == 1.0L) ) - return y - y; /* +-1**inf is NaN */ - -if( x == 1.0L ) +if( !isfinite(y) && x == -1.0L ) return( 1.0L ); if( y >= LDBL_MAX ) diff --git a/regress/lib/libm/cephes/testvect.c b/regress/lib/libm/cephes/testvect.c index 638320074e7..5bb328205aa 100644 --- a/regress/lib/libm/cephes/testvect.c +++ b/regress/lib/libm/cephes/testvect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: testvect.c,v 1.1 2011/05/30 20:23:35 martynas Exp $ */ +/* $OpenBSD: testvect.c,v 1.2 2013/08/02 20:23:28 kettenis Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> @@ -332,12 +332,12 @@ static struct twoarguments test2[] = {"pow", pow, &MINF, &MTHREE, &MZERO, 0}, {"pow", pow, &MINF, &MTWO, &ZERO, 0}, {"pow", pow, &NAN, &ONE, &NAN, 0}, - {"pow", pow, &ONE, &NAN, &NAN, 0}, + {"pow", pow, &ONE, &NAN, &ONE, 0}, {"pow", pow, &NAN, &NAN, &NAN, 0}, - {"pow", pow, &ONE, &INF, &NAN, 0}, - {"pow", pow, &MONE, &INF, &NAN, 0}, - {"pow", pow, &ONE, &MINF, &NAN, 0}, - {"pow", pow, &MONE, &MINF, &NAN, 0}, + {"pow", pow, &ONE, &INF, &ONE, 0}, + {"pow", pow, &MONE, &INF, &ONE, 0}, + {"pow", pow, &ONE, &MINF, &ONE, 0}, + {"pow", pow, &MONE, &MINF, &ONE, 0}, {"pow", pow, &MTWO, &HALF, &NAN, 0}, {"pow", pow, &ZERO, &MTHREE, &INF, 0}, {"pow", pow, &MZERO, &MTHREE, &MINF, 0}, diff --git a/regress/lib/libm/cephes/testvectl.c b/regress/lib/libm/cephes/testvectl.c index 2f4355764bb..c0436eb6263 100644 --- a/regress/lib/libm/cephes/testvectl.c +++ b/regress/lib/libm/cephes/testvectl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: testvectl.c,v 1.2 2011/07/08 16:49:05 martynas Exp $ */ +/* $OpenBSD: testvectl.c,v 1.3 2013/08/02 20:23:28 kettenis Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> @@ -325,12 +325,12 @@ static struct twoarguments test2[] = {"powl", powl, &MINFL, &MTHREEL, &NEGZEROL, 0}, {"powl", powl, &MINFL, &MTWOL, &ZEROL, 0}, {"powl", powl, &NANL, &ONEL, &NANL, 0}, - {"powl", powl, &ONEL, &NANL, &NANL, 0}, + {"powl", powl, &ONEL, &NANL, &ONEL, 0}, {"powl", powl, &NANL, &NANL, &NANL, 0}, - {"powl", powl, &ONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &MONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &ONEL, &MINFL, &NANL, 0}, - {"powl", powl, &MONEL, &MINFL, &NANL, 0}, + {"powl", powl, &ONEL, &INFINITYL, &ONEL, 0}, + {"powl", powl, &MONEL, &INFINITYL, &ONEL, 0}, + {"powl", powl, &ONEL, &MINFL, &ONEL, 0}, + {"powl", powl, &MONEL, &MINFL, &ONEL, 0}, {"powl", powl, &MTWOL, &HALFL, &NANL, 0}, {"powl", powl, &ZEROL, &MTHREEL, &INFINITYL, 0}, {"powl", powl, &NEGZEROL, &MTHREEL, &MINFL, 0}, diff --git a/regress/lib/libm/cephes/testvectll.c b/regress/lib/libm/cephes/testvectll.c index 37e4f81dc80..b4984344785 100644 --- a/regress/lib/libm/cephes/testvectll.c +++ b/regress/lib/libm/cephes/testvectll.c @@ -1,4 +1,4 @@ -/* $OpenBSD: testvectll.c,v 1.2 2011/07/08 16:49:05 martynas Exp $ */ +/* $OpenBSD: testvectll.c,v 1.3 2013/08/02 20:23:28 kettenis Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> @@ -328,12 +328,12 @@ static struct twoarguments test2[] = {"powl", powl, &MINFL, &MTHREEL, &NEGZEROL, 0}, {"powl", powl, &MINFL, &MTWOL, &ZEROL, 0}, {"powl", powl, &NANL, &ONEL, &NANL, 0}, - {"powl", powl, &ONEL, &NANL, &NANL, 0}, + {"powl", powl, &ONEL, &NANL, &ONEL, 0}, {"powl", powl, &NANL, &NANL, &NANL, 0}, - {"powl", powl, &ONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &MONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &ONEL, &MINFL, &NANL, 0}, - {"powl", powl, &MONEL, &MINFL, &NANL, 0}, + {"powl", powl, &ONEL, &INFINITYL, &ONEL, 0}, + {"powl", powl, &MONEL, &INFINITYL, &ONEL, 0}, + {"powl", powl, &ONEL, &MINFL, &ONEL, 0}, + {"powl", powl, &MONEL, &MINFL, &ONEL, 0}, {"powl", powl, &MTWOL, &HALFL, &NANL, 0}, {"powl", powl, &ZEROL, &MTHREEL, &INFINITYL, 0}, {"powl", powl, &NEGZEROL, &MTHREEL, &MINFL, 0}, |