diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_sin.c | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/k_sinf.c | 11 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/k_sincosl.c | 20 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/k_sinl.c | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/k_sincosl.c | 20 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/k_sinl.c | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/k_sinl.c | 10 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/k_sinf.c | 6 |
8 files changed, 79 insertions, 18 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c index ea89ad5..eff120e 100644 --- a/sysdeps/ieee754/dbl-64/s_sin.c +++ b/sysdeps/ieee754/dbl-64/s_sin.c @@ -48,6 +48,7 @@ #include <errno.h> +#include <float.h> #include "endian.h" #include "mydefs.h" #include "usncs.h" @@ -295,7 +296,14 @@ __sin (double x) m = u.i[HIGH_HALF]; k = 0x7fffffff & m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ - retval = x; + { + if (fabs (x) < DBL_MIN) + { + double force_underflow = x * x; + math_force_eval (force_underflow); + } + retval = x; + } /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/ else if (k < 0x3fd00000) { diff --git a/sysdeps/ieee754/flt-32/k_sinf.c b/sysdeps/ieee754/flt-32/k_sinf.c index 0bafd83..0c98a2a 100644 --- a/sysdeps/ieee754/flt-32/k_sinf.c +++ b/sysdeps/ieee754/flt-32/k_sinf.c @@ -17,6 +17,7 @@ static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $"; #endif +#include <float.h> #include <math.h> #include <math_private.h> @@ -36,7 +37,15 @@ float __kernel_sinf(float x, float y, int iy) GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* high word of x */ if(ix<0x32000000) /* |x| < 2**-27 */ - {if((int)x==0) return x;} /* generate inexact */ + { + if (fabsf (x) < FLT_MIN) + { + float force_underflow = x * x; + math_force_eval (force_underflow); + } + if ((int) x == 0) + return x; /* generate inexact */ + } z = x*x; v = z*x; r = S2+z*(S3+z*(S4+z*(S5+z*S6))); diff --git a/sysdeps/ieee754/ldbl-128/k_sincosl.c b/sysdeps/ieee754/ldbl-128/k_sincosl.c index 2f66dee..7b5c4b0 100644 --- a/sysdeps/ieee754/ldbl-128/k_sincosl.c +++ b/sysdeps/ieee754/ldbl-128/k_sincosl.c @@ -17,6 +17,7 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <float.h> #include <math.h> #include <math_private.h> @@ -109,12 +110,19 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 16(17). */ if (tix < 0x3fc60000) /* |x| < 2^-57 */ - if (!((int)x)) /* generate inexact */ - { - *sinx = x; - *cosx = ONE; - return; - } + { + if (fabsl (x) < LDBL_MIN) + { + long double force_underflow = x * x; + math_force_eval (force_underflow); + } + if (!((int)x)) /* generate inexact */ + { + *sinx = x; + *cosx = ONE; + return; + } + } z = x * x; *sinx = x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); diff --git a/sysdeps/ieee754/ldbl-128/k_sinl.c b/sysdeps/ieee754/ldbl-128/k_sinl.c index b15521b..04d539f 100644 --- a/sysdeps/ieee754/ldbl-128/k_sinl.c +++ b/sysdeps/ieee754/ldbl-128/k_sinl.c @@ -17,6 +17,7 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <float.h> #include <math.h> #include <math_private.h> @@ -90,7 +91,14 @@ __kernel_sinl(long double x, long double y, int iy) /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 17. */ if (tix < 0x3fc60000) /* |x| < 2^-57 */ - if (!((int)x)) return x; /* generate inexact */ + { + if (fabsl (x) < LDBL_MIN) + { + long double force_underflow = x * x; + math_force_eval (force_underflow); + } + if (!((int)x)) return x; /* generate inexact */ + } z = x * x; return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c index f831e3f..0a76e1c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c @@ -17,6 +17,7 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <float.h> #include <math.h> #include <math_private.h> @@ -112,12 +113,19 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 16(17). */ if (tix < 0x3c600000) /* |x| < 2^-57 */ - if (!((int)x)) /* generate inexact */ - { - *sinx = x; - *cosx = ONE; - return; - } + { + if (fabsl (x) < LDBL_MIN) + { + long double force_underflow = x * x; + math_force_eval (force_underflow); + } + if (!((int)x)) /* generate inexact */ + { + *sinx = x; + *cosx = ONE; + return; + } + } z = x * x; *sinx = x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c index d6602fe..2050cd2 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c @@ -17,6 +17,7 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <float.h> #include <math.h> #include <math_private.h> @@ -93,7 +94,14 @@ __kernel_sinl(long double x, long double y, int iy) /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 17. */ if (tix < 0x3c600000) /* |x| < 2^-57 */ - if (!((int)x)) return x; /* generate inexact */ + { + if (fabsl (x) < LDBL_MIN) + { + long double force_underflow = x * x; + math_force_eval (force_underflow); + } + if (!((int)x)) return x; /* generate inexact */ + } z = x * x; return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); diff --git a/sysdeps/ieee754/ldbl-96/k_sinl.c b/sysdeps/ieee754/ldbl-96/k_sinl.c index 179262a..b7b5ae3 100644 --- a/sysdeps/ieee754/ldbl-96/k_sinl.c +++ b/sysdeps/ieee754/ldbl-96/k_sinl.c @@ -20,6 +20,7 @@ /* The polynomials have not been optimized for extended-precision and may contain more terms than needed. */ +#include <float.h> #include <math.h> #include <math_private.h> @@ -94,7 +95,14 @@ __kernel_sinl(long double x, long double y, int iy) /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 17. */ if (absx < 0x1p-33L) - if (!((int)x)) return x; /* generate inexact */ + { + if (fabsl (x) < LDBL_MIN) + { + long double force_underflow = x * x; + math_force_eval (force_underflow); + } + if (!((int)x)) return x; /* generate inexact */ + } z = x * x; return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); diff --git a/sysdeps/powerpc/fpu/k_sinf.c b/sysdeps/powerpc/fpu/k_sinf.c index 64df0c9..e2850df 100644 --- a/sysdeps/powerpc/fpu/k_sinf.c +++ b/sysdeps/powerpc/fpu/k_sinf.c @@ -17,6 +17,7 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, see <http://www.gnu.org/licenses/>. */ +#include <float.h> #include <math.h> #include <fenv.h> #include <math_private.h> @@ -40,7 +41,10 @@ __kernel_sinf (float x, float y, int iy) ix = __builtin_fabsf (x); if (ix < twom27) { /* |x| < 2**-27 */ - __feraiseexcept (FE_INEXACT); + if (ix < FLT_MIN && ix != 0.0f) + __feraiseexcept (FE_UNDERFLOW|FE_INEXACT); + else + __feraiseexcept (FE_INEXACT); return x; } z = x * x; |