From a8c4a5e0ff6ecd6f36ed684b7cdbadfd417be1b7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 11 Dec 2007 13:04:17 +0000 Subject: * libm/math/w_atan2.c: Fix atan2 to be consistent with glibc (atan2(+0,-0), atan2(-0,-0) and atan(-0,+0)) * libm/math/wf_atan2.c: Ditto. * libm/math/e_pow.c: Fix to be consistent with glibc with regards to treatment of NaN and +-inf arguments. * libm/math/ef_pow.c: Ditto. * libm/math/w_pow.c: Ditto. * libm/math/wf_pow.c: Ditto. * libm/math/w_acos.c: Fix domain errors to return NaN. * libm/math/w_asin.c: Ditto. * libm/math/wf_acos.c: Ditto. * libm/math/wf_asin.c: Ditto. * libm/math/w_log.c: Fix to return NaN for negative number inputs. * libm/math/wf_log.c: Ditto. * libm/math/wf_log10.c: Ditto. * libm/math/w_log10.c: Ditto. --- newlib/ChangeLog | 22 ++++++++++++++++++++++ newlib/libm/math/e_pow.c | 12 +++++++----- newlib/libm/math/ef_pow.c | 7 ++++--- newlib/libm/math/w_acos.c | 2 +- newlib/libm/math/w_asin.c | 2 +- newlib/libm/math/w_atan2.c | 27 --------------------------- newlib/libm/math/w_log.c | 3 ++- newlib/libm/math/w_log10.c | 1 + newlib/libm/math/w_pow.c | 2 +- newlib/libm/math/wf_acos.c | 2 +- newlib/libm/math/wf_asin.c | 2 +- newlib/libm/math/wf_atan2.c | 25 ------------------------- newlib/libm/math/wf_log.c | 1 + newlib/libm/math/wf_log10.c | 1 + newlib/libm/math/wf_pow.c | 2 +- 15 files changed, 44 insertions(+), 67 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 64e0a5a..52a2882 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -138,6 +138,12 @@ * libc/include/argz.h: Guard against multiple inclusion. Guard for use with C++. +2007-05-17 Cary R. yahoo.com> + + * libm/math/w_atan2.c: Fix atan2 to be consistent with glibc + (atan2(+0,-0), atan2(-0,-0) and atan(-0,+0)) + * libm/math/wf_atan2.c: Ditto. + 2007-05-17 Charles Wilson * stdio/tmpfile.c: Include . @@ -182,6 +188,22 @@ * libc/stdio/makebuf.c (__smakebuf_r): Likewise. * libc/stdio/mktemp.c (_gettemp): Likewise. +2007-05-01 Cary R. yahoo.com> + + * libm/math/e_pow.c: Fix to be consistent with glibc with regards to + treatment of NaN and +-inf arguments. + * libm/math/ef_pow.c: Ditto. + * libm/math/w_pow.c: Ditto. + * libm/math/wf_pow.c: Ditto. + * libm/math/w_acos.c: Fix domain errors to return NaN. + * libm/math/w_asin.c: Ditto. + * libm/math/wf_acos.c: Ditto. + * libm/math/wf_asin.c: Ditto. + * libm/math/w_log.c: Fix to return NaN for negative number inputs. + * libm/math/wf_log.c: Ditto. + * libm/math/wf_log10.c: Ditto. + * libm/math/w_log10.c: Ditto. + 2007-04-25 Eric Blake * libc/stdio/vfprintf.c (get_arg): Support %1$lc. Simplify types diff --git a/newlib/libm/math/e_pow.c b/newlib/libm/math/e_pow.c index 56c7980..aac0b42 100644 --- a/newlib/libm/math/e_pow.c +++ b/newlib/libm/math/e_pow.c @@ -25,13 +25,14 @@ * Special cases: * 1. (anything) ** 0 is 1 * 2. (anything) ** 1 is itself - * 3. (anything) ** NAN is NAN + * 3a. (anything) ** NAN is NAN except + * 3b. +1 ** NAN is 1 * 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 @@ -117,10 +118,11 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ /* y==zero: x**0 = 1 */ if((iy|ly)==0) return one; - /* +-NaN return x+y */ + /* x|y==NaN return NaN unless x==1 then return 1 */ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) - return x+y; + if(((ix-0x3ff00000)|lx)==0) return one; + else return nan(""); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer @@ -146,7 +148,7 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ 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 = 1 */ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ diff --git a/newlib/libm/math/ef_pow.c b/newlib/libm/math/ef_pow.c index 8b1fc18..6804ce4 100644 --- a/newlib/libm/math/ef_pow.c +++ b/newlib/libm/math/ef_pow.c @@ -75,10 +75,11 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ /* y==zero: x**0 = 1 */ if(FLT_UWORD_IS_ZERO(iy)) return one; - /* +-NaN return x+y */ + /* x|y==NaN return NaN unless x==1 then return 1 */ if(FLT_UWORD_IS_NAN(ix) || FLT_UWORD_IS_NAN(iy)) - return x+y; + if(ix==0x3f800000) return one; + else return nanf(""); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer @@ -98,7 +99,7 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ /* special value of y */ if (FLT_UWORD_IS_INFINITE(iy)) { /* y is +-inf */ if (ix==0x3f800000) - return y - y; /* inf**+-1 is NaN */ + return one; /* +-1**+-inf = 1 */ else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ diff --git a/newlib/libm/math/w_acos.c b/newlib/libm/math/w_acos.c index 0a4823f..fdf2eb0 100644 --- a/newlib/libm/math/w_acos.c +++ b/newlib/libm/math/w_acos.c @@ -101,7 +101,7 @@ MATHREF exc.name = "acos"; exc.err = 0; exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; + exc.retval = nan(""); if (_LIB_VERSION == _POSIX_) errno = EDOM; else if (!matherr(&exc)) { diff --git a/newlib/libm/math/w_asin.c b/newlib/libm/math/w_asin.c index b146dfd..e7884b2 100644 --- a/newlib/libm/math/w_asin.c +++ b/newlib/libm/math/w_asin.c @@ -104,7 +104,7 @@ MATHREF exc.name = "asin"; exc.err = 0; exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; + exc.retval = nan(""); if(_LIB_VERSION == _POSIX_) errno = EDOM; else if (!matherr(&exc)) { diff --git a/newlib/libm/math/w_atan2.c b/newlib/libm/math/w_atan2.c index 25eb161..f3e344e 100644 --- a/newlib/libm/math/w_atan2.c +++ b/newlib/libm/math/w_atan2.c @@ -60,8 +60,6 @@ RETURNS $-\pi$ to $\pi$. @end tex -If both <[x]> and <[y]> are 0.0, <> causes a <> error. - You can modify error handling for these functions using <>. PORTABILITY @@ -86,32 +84,7 @@ PORTABILITY double y,x; #endif { -#ifdef _IEEE_LIBM return __ieee754_atan2(y,x); -#else - double z; - struct exception exc; - z = __ieee754_atan2(y,x); - if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z; - if(x==0.0&&y==0.0) { - /* atan2(+-0,+-0) */ - exc.arg1 = y; - exc.arg2 = x; - exc.type = DOMAIN; - exc.name = "atan2"; - exc.err = 0; - exc.retval = 0.0; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; - } else - return z; -#endif } #endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/newlib/libm/math/w_log.c b/newlib/libm/math/w_log.c index 3e750ad..e23efd7 100644 --- a/newlib/libm/math/w_log.c +++ b/newlib/libm/math/w_log.c @@ -44,7 +44,7 @@ handling for these functions. RETURNS Normally, returns the calculated value. When <[x]> is zero, the returned value is <<-HUGE_VAL>> and <> is set to <>. -When <[x]> is negative, the returned value is <<-HUGE_VAL>> and +When <[x]> is negative, the returned value is NaN (not a number) and <> is set to <>. You can control the error behavior via <>. @@ -105,6 +105,7 @@ PORTABILITY else if (!matherr(&exc)) { errno = EDOM; } + exc.retval = nan(""); } if (exc.err != 0) errno = exc.err; diff --git a/newlib/libm/math/w_log10.c b/newlib/libm/math/w_log10.c index f427b86..7c39669 100644 --- a/newlib/libm/math/w_log10.c +++ b/newlib/libm/math/w_log10.c @@ -103,6 +103,7 @@ PORTABILITY else if (!matherr(&exc)) { errno = EDOM; } + exc.retval = nan(""); } if (exc.err != 0) errno = exc.err; diff --git a/newlib/libm/math/w_pow.c b/newlib/libm/math/w_pow.c index d54cd3a..2e08619 100644 --- a/newlib/libm/math/w_pow.c +++ b/newlib/libm/math/w_pow.c @@ -93,7 +93,7 @@ PORTABILITY exc.err = 0; exc.arg1 = x; exc.arg2 = y; - exc.retval = x; + exc.retval = 1.0; if (_LIB_VERSION == _IEEE_ || _LIB_VERSION == _POSIX_) exc.retval = 1.0; else if (!matherr(&exc)) { diff --git a/newlib/libm/math/wf_acos.c b/newlib/libm/math/wf_acos.c index 8a10374..38817b8 100644 --- a/newlib/libm/math/wf_acos.c +++ b/newlib/libm/math/wf_acos.c @@ -40,7 +40,7 @@ exc.name = "acosf"; exc.err = 0; exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; + exc.retval = nan(""); if (_LIB_VERSION == _POSIX_) errno = EDOM; else if (!matherr(&exc)) { diff --git a/newlib/libm/math/wf_asin.c b/newlib/libm/math/wf_asin.c index a5225f2..fc39e97 100644 --- a/newlib/libm/math/wf_asin.c +++ b/newlib/libm/math/wf_asin.c @@ -42,7 +42,7 @@ exc.name = "asinf"; exc.err = 0; exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; + exc.retval = nan(""); if(_LIB_VERSION == _POSIX_) errno = EDOM; else if (!matherr(&exc)) { diff --git a/newlib/libm/math/wf_atan2.c b/newlib/libm/math/wf_atan2.c index 069a7ca..eb2a76b 100644 --- a/newlib/libm/math/wf_atan2.c +++ b/newlib/libm/math/wf_atan2.c @@ -28,32 +28,7 @@ float y,x; #endif { -#ifdef _IEEE_LIBM return __ieee754_atan2f(y,x); -#else - float z; - struct exception exc; - z = __ieee754_atan2f(y,x); - if(_LIB_VERSION == _IEEE_||isnanf(x)||isnanf(y)) return z; - if(x==(float)0.0&&y==(float)0.0) { - /* atan2f(+-0,+-0) */ - exc.arg1 = y; - exc.arg2 = x; - exc.err = 0; - exc.type = DOMAIN; - exc.name = "atan2f"; - exc.retval = 0.0; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; - } else - return z; -#endif } #ifdef _DOUBLE_IS_32BITS diff --git a/newlib/libm/math/wf_log.c b/newlib/libm/math/wf_log.c index cd373b4..369ef32 100644 --- a/newlib/libm/math/wf_log.c +++ b/newlib/libm/math/wf_log.c @@ -63,6 +63,7 @@ else if (!matherr(&exc)) { errno = EDOM; } + exc.retval = nan(""); } if (exc.err != 0) errno = exc.err; diff --git a/newlib/libm/math/wf_log10.c b/newlib/libm/math/wf_log10.c index 15fa5d9..7289135 100644 --- a/newlib/libm/math/wf_log10.c +++ b/newlib/libm/math/wf_log10.c @@ -64,6 +64,7 @@ else if (!matherr(&exc)) { errno = EDOM; } + exc.retval = nan(""); } if (exc.err != 0) errno = exc.err; diff --git a/newlib/libm/math/wf_pow.c b/newlib/libm/math/wf_pow.c index 42655da..eaeed85 100644 --- a/newlib/libm/math/wf_pow.c +++ b/newlib/libm/math/wf_pow.c @@ -43,7 +43,7 @@ exc.err = 0; exc.arg1 = (double)x; exc.arg2 = (double)y; - exc.retval = x; + exc.retval = 1.0; if (_LIB_VERSION == _IEEE_ || _LIB_VERSION == _POSIX_) exc.retval = 1.0; else if (!matherr(&exc)) { -- cgit v1.1