diff options
author | 2013-08-02 20:23:28 +0000 | |
---|---|---|
committer | 2013-08-02 20:23:28 +0000 | |
commit | d205ab02eabefec09df68de8ff35e0519ffc9a86 (patch) | |
tree | bd1af2e134d4ae75481b006c069142022a9a87d2 /lib/libm/src/e_pow.c | |
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@
Diffstat (limited to 'lib/libm/src/e_pow.c')
-rw-r--r-- | lib/libm/src/e_pow.c | 9 |
1 files changed, 6 insertions, 3 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 */ |