diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-03-03 18:18:04 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-03-03 18:18:04 +0000 |
commit | c0102611b1f1bd1ce2a2952e9b74ff33fa02717e (patch) | |
tree | 31177266a6797f3c30d0493619d0f06f3f59afe1 /libc/sysdeps/ieee754/dbl-64 | |
parent | 33f3f8954d202664c7c7a224d13ba5a0c14a0e01 (diff) |
Merge changes between r17194 and r17384 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@17385 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/ieee754/dbl-64')
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/e_atanh.c | 8 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/e_exp.c | 38 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/k_tan.c | 137 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/s_scalbln.c | 8 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/s_scalbn.c | 8 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/s_sin.c | 109 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/s_tan.c | 117 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/w_exp.c | 6 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c | 8 | ||||
-rw-r--r-- | libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c | 8 |
10 files changed, 195 insertions, 252 deletions
diff --git a/libc/sysdeps/ieee754/dbl-64/e_atanh.c b/libc/sysdeps/ieee754/dbl-64/e_atanh.c index 9fc21abe2..5f471b1d7 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_atanh.c +++ b/libc/sysdeps/ieee754/dbl-64/e_atanh.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Free Software Foundation, Inc. +/* Copyright (C) 2011, 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@gmail.com>, 2011. @@ -46,7 +46,7 @@ __ieee754_atanh (double x) { double xa = fabs (x); double t; - if (xa < 0.5) + if (isless (xa, 0.5)) { if (__builtin_expect (xa < 0x1.0p-28, 0)) { @@ -57,11 +57,11 @@ __ieee754_atanh (double x) t = xa + xa; t = 0.5 * __log1p (t + t * xa / (1.0 - xa)); } - else if (__builtin_expect (xa < 1.0, 1)) + else if (__builtin_expect (isless (xa, 1.0), 1)) t = 0.5 * __log1p ((xa + xa) / (1.0 - xa)); else { - if (xa > 1.0) + if (isgreater (xa, 1.0)) return (x - x) / (x - x); return x / 0.0; diff --git a/libc/sysdeps/ieee754/dbl-64/e_exp.c b/libc/sysdeps/ieee754/dbl-64/e_exp.c index cfdb8e2c7..8231c5698 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_exp.c +++ b/libc/sysdeps/ieee754/dbl-64/e_exp.c @@ -1,7 +1,7 @@ /* * IBM Accurate Mathematical Library * written by International Business Machines Corp. - * Copyright (C) 2001, 2011 Free Software Foundation + * Copyright (C) 2001-2012 Free Software Foundation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -38,6 +38,7 @@ #include "MathLib.h" #include "uexp.tbl" #include "math_private.h" +#include <fenv.h> #ifndef SECTION # define SECTION @@ -58,6 +59,10 @@ __ieee754_exp(double x) { int4 k; #endif int4 i,j,m,n,ex; + fenv_t env; + double retval; + + libc_feholdexcept_setround (&env, FE_TONEAREST); junk1.x = x; m = junk1.i[HIGH_HALF]; @@ -90,18 +95,19 @@ __ieee754_exp(double x) { rem=(bet + bet*eps)+al*eps; res = al + rem; cor = (al - res) + rem; - if (res == (res+cor*err_0)) return res*binexp.x; - else return __slowexp(x); /*if error is over bound */ + if (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; } + else { retval = __slowexp(x); goto ret; } /*if error is over bound */ } - if (n <= smallint) return 1.0; + if (n <= smallint) { retval = 1.0; goto ret; } if (n >= badint) { - if (n > infint) return(x+x); /* x is NaN */ - if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) ); + if (n > infint) { retval = x+x; goto ret; } /* x is NaN */ + if (n < infint) { retval = (x>0) ? (hhuge*hhuge) : (tiny*tiny); goto ret; } /* x is finite, cause either overflow or underflow */ - if (junk1.i[LOW_HALF] != 0) return (x+x); /* x is NaN */ - return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */ + if (junk1.i[LOW_HALF] != 0) { retval = x+x; goto ret; } /* x is NaN */ + retval = (x>0)?inf.x:zero; /* |x| = inf; return either inf or 0 */ + goto ret; } y = x*log2e.x + three51.x; @@ -126,8 +132,8 @@ __ieee754_exp(double x) { if (res < 1.0) {res+=res; cor+=cor; ex-=1;} if (ex >=-1022) { binexp.i[HIGH_HALF] = (1023+ex)<<20; - if (res == (res+cor*err_0)) return res*binexp.x; - else return __slowexp(x); /*if error is over bound */ + if (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; } + else { retval = __slowexp(x); goto ret; } /*if error is over bound */ } ex = -(1022+ex); binexp.i[HIGH_HALF] = (1023-ex)<<20; @@ -140,15 +146,19 @@ __ieee754_exp(double x) { cor = (t-res)+y; if (res == (res + eps*cor)) { binexp.i[HIGH_HALF] = 0x00100000; - return (res-1.0)*binexp.x; + retval = (res-1.0)*binexp.x; + goto ret; } - else return __slowexp(x); /* if error is over bound */ + else { retval = __slowexp(x); goto ret; } /* if error is over bound */ } else { binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20; - if (res == (res+cor*err_0)) return res*binexp.x*t256.x; - else return __slowexp(x); + if (res == (res+cor*err_0)) { retval = res*binexp.x*t256.x; goto ret; } + else { retval = __slowexp(x); goto ret; } } + ret: + libc_feupdateenv (&env); + return retval; } #ifndef __ieee754_exp strong_alias (__ieee754_exp, __exp_finite) diff --git a/libc/sysdeps/ieee754/dbl-64/k_tan.c b/libc/sysdeps/ieee754/dbl-64/k_tan.c index 7ef4103bc..cc5c205a5 100644 --- a/libc/sysdeps/ieee754/dbl-64/k_tan.c +++ b/libc/sysdeps/ieee754/dbl-64/k_tan.c @@ -1,136 +1 @@ -/* @(#)k_tan.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25, - for performance improvement on pipelined processors. -*/ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: k_tan.c,v 1.8 1995/05/10 20:46:37 jtc Exp $"; -#endif - -/* __kernel_tan( x, y, k ) - * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 - * Input x is assumed to be bounded by ~pi/4 in magnitude. - * Input y is the tail of x. - * Input k indicates whether tan (if k=1) or - * -1/tan (if k= -1) is returned. - * - * Algorithm - * 1. Since tan(-x) = -tan(x), we need only to consider positive x. - * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. - * 3. tan(x) is approximated by a odd polynomial of degree 27 on - * [0,0.67434] - * 3 27 - * tan(x) ~ x + T1*x + ... + T13*x - * where - * - * |tan(x) 2 4 26 | -59.2 - * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 - * | x | - * - * Note: tan(x+y) = tan(x) + tan'(x)*y - * ~ tan(x) + (1+x*x)*y - * Therefore, for better accuracy in computing tan(x+y), let - * 3 2 2 2 2 - * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) - * then - * 3 2 - * tan(x+y) = x + (T1*x + (x *(r+y)+y)) - * - * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then - * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) - * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) - */ - -#include "math.h" -#include "math_private.h" -static const double -one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ -pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ -pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ -T[] = { - 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ - 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ - 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ - 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ - 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ - 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ - 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ - 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ - 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ - 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ - 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ - -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ - 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ -}; - -double __kernel_tan(double x, double y, int iy) -{ - double z,r,v,w,s,r1,r2,r3,v1,v2,v3,w2,w4; - int32_t ix,hx; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; /* high word of |x| */ - if(ix<0x3e300000) /* x < 2**-28 */ - {if((int)x==0) { /* generate inexact */ - u_int32_t low; - GET_LOW_WORD(low,x); - if(((ix|low)|(iy+1))==0) return one/fabs(x); - else return (iy==1)? x: -one/x; - } - } - if(ix>=0x3FE59428) { /* |x|>=0.6744 */ - if(hx<0) {x = -x; y = -y;} - z = pio4-x; - w = pio4lo-y; - x = z+w; y = 0.0; - } - z = x*x; - w = z*z; - /* Break x^5*(T[1]+x^2*T[2]+...) into - * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + - * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) - */ -#ifdef DO_NOT_USE_THIS - r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); - v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); -#else - v1 = T[10]+w*T[12]; w2=w*w; - v2 = T[6]+w*T[8]; w4=w2*w2; - v3 = T[2]+w*T[4]; v1=z*v1; - r1 = T[9]+w*T[11]; v2=z*v2; - r2 = T[5]+w*T[7]; v3=z*v3; - r3 = T[1]+w*T[3]; - v = v3 + w2*v2 + w4*v1; - r = r3 + w2*r2 + w4*r1; -#endif - s = z*x; - r = y + z*(s*(r+v)+y); - r += T[0]*s; - w = x+r; - if(ix>=0x3FE59428) { - v = (double)iy; - return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r))); - } - if(iy==1) return w; - else { /* if allow error up to 2 ulp, - simply return -1.0/(x+r) here */ - /* compute -1.0/(x+r) accurately */ - double a,t; - z = w; - SET_LOW_WORD(z,0); - v = r-(z - x); /* z+v = r+x */ - t = a = -1.0/w; /* a = -1.0/w */ - SET_LOW_WORD(t,0); - s = 1.0+t*z; - return t+a*(s+t*v); - } -} +/* Not needed anymore. */ diff --git a/libc/sysdeps/ieee754/dbl-64/s_scalbln.c b/libc/sysdeps/ieee754/dbl-64/s_scalbln.c index 89174b47f..b5903c97d 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_scalbln.c +++ b/libc/sysdeps/ieee754/dbl-64/s_scalbln.c @@ -38,11 +38,13 @@ __scalbln (double x, long int n) k = ((hx&0x7ff00000)>>20) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) diff --git a/libc/sysdeps/ieee754/dbl-64/s_scalbn.c b/libc/sysdeps/ieee754/dbl-64/s_scalbn.c index 1e67dbe5e..c2488fbbe 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_scalbn.c +++ b/libc/sysdeps/ieee754/dbl-64/s_scalbn.c @@ -38,11 +38,13 @@ __scalbn (double x, int n) k = ((hx&0x7ff00000)>>20) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) diff --git a/libc/sysdeps/ieee754/dbl-64/s_sin.c b/libc/sysdeps/ieee754/dbl-64/s_sin.c index 5b7985400..32ba66d1a 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_sin.c +++ b/libc/sysdeps/ieee754/dbl-64/s_sin.c @@ -53,6 +53,7 @@ #include "usncs.h" #include "MathLib.h" #include "math_private.h" +#include <fenv.h> #ifndef SECTION # define SECTION @@ -107,12 +108,16 @@ __sin(double x){ #if 0 int4 nn; #endif + fenv_t env; + double retval = 0; + + libc_feholdexcept_setround (&env, FE_TONEAREST); u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff&m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ - return x; + { retval = x; goto ret; } /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/ else if (k < 0x3fd00000){ xx = x*x; @@ -120,7 +125,8 @@ __sin(double x){ t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x); res = x+t; cor = (x-res)+t; - return (res == res + 1.07*cor)? res : slow(x); + retval = (res == res + 1.07*cor)? res : slow(x); + goto ret; } /* else if (k < 0x3fd00000) */ /*---------------------------- 0.25<|x|< 0.855469---------------------- */ else if (k < 0x3feb6000) { @@ -137,7 +143,8 @@ __sin(double x){ cor=(ssn+s*ccs-sn*c)+cs*s; res=sn+cor; cor=(sn-res)+cor; - return (res==res+1.096*cor)? res : slow1(x); + retval = (res==res+1.096*cor)? res : slow1(x); + goto ret; } /* else if (k < 0x3feb6000) */ /*----------------------- 0.855469 <|x|<2.426265 ----------------------*/ @@ -163,7 +170,8 @@ __sin(double x){ cor=(ccs-s*ssn-cs*c)-sn*s; res=cs+cor; cor=(cs-res)+cor; - return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x); + retval = (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x); + goto ret; } /* else if (k < 0x400368fd) */ /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/ @@ -189,7 +197,8 @@ __sin(double x){ res = a+t; cor = (a-res)+t; cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps; - return (res == res + cor)? res : sloww(a,da,x); + retval = (res == res + cor)? res : sloww(a,da,x); + goto ret; } else { if (a>0) @@ -210,7 +219,8 @@ __sin(double x){ res=sn+cor; cor=(sn-res)+cor; cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps; - return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x); + retval = (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x); + goto ret; } break; @@ -232,7 +242,8 @@ __sin(double x){ res=cs+cor; cor=(cs-res)+cor; cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps; - return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n); + retval = (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n); + goto ret; break; @@ -268,7 +279,8 @@ __sin(double x){ res = a+t; cor = (a-res)+t; cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps; - return (res == res + cor)? res : bsloww(a,da,x,n); + retval = (res == res + cor)? res : bsloww(a,da,x,n); + goto ret; } else { if (a>0) {m=1;t=a;db=da;} @@ -287,7 +299,8 @@ __sin(double x){ res=sn+cor; cor=(sn-res)+cor; cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps; - return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n); + retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n); + goto ret; } break; @@ -309,7 +322,8 @@ __sin(double x){ res=cs+cor; cor=(cs-res)+cor; cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps; - return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n); + retval = (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n); + goto ret; break; @@ -323,17 +337,20 @@ __sin(double x){ n = __branred(x,&a,&da); switch (n) { case 0: - if (a*a < 0.01588) return bsloww(a,da,x,n); - else return bsloww1(a,da,x,n); + if (a*a < 0.01588) retval = bsloww(a,da,x,n); + else retval = bsloww1(a,da,x,n); + goto ret; break; case 2: - if (a*a < 0.01588) return bsloww(-a,-da,x,n); - else return bsloww1(-a,-da,x,n); + if (a*a < 0.01588) retval = bsloww(-a,-da,x,n); + else retval = bsloww1(-a,-da,x,n); + goto ret; break; case 1: case 3: - return bsloww2(a,da,x,n); + retval = bsloww2(a,da,x,n); + goto ret; break; } @@ -343,9 +360,13 @@ __sin(double x){ else { if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); - return x / x; + retval = x / x; + goto ret; } - return 0; /* unreachable */ + + ret: + libc_feupdateenv (&env); + return retval; } @@ -362,11 +383,16 @@ __cos(double x) mynumber u,v; int4 k,m,n; + fenv_t env; + double retval = 0; + + libc_feholdexcept_setround (&env, FE_TONEAREST); + u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff&m; - if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */ + if (k < 0x3e400000 ) { retval = 1.0; goto ret; } /* |x|<2^-27 => cos(x)=1 */ else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */ y=ABS(x); @@ -383,7 +409,8 @@ __cos(double x) cor=(ccs-s*ssn-cs*c)-sn*s; res=cs+cor; cor=(cs-res)+cor; - return (res==res+1.020*cor)? res : cslow2(x); + retval = (res==res+1.020*cor)? res : cslow2(x); + goto ret; } /* else if (k < 0x3feb6000) */ @@ -397,7 +424,8 @@ __cos(double x) res = a+t; cor = (a-res)+t; cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31; - return (res == res + cor)? res : csloww(a,da,x); + retval = (res == res + cor)? res : csloww(a,da,x); + goto ret; } else { if (a>0) {m=1;t=a;db=da;} @@ -416,7 +444,8 @@ __cos(double x) res=sn+cor; cor=(sn-res)+cor; cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31; - return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x); + retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x); + goto ret; } } /* else if (k < 0x400368fd) */ @@ -443,7 +472,8 @@ __cos(double x) res = a+t; cor = (a-res)+t; cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps; - return (res == res + cor)? res : csloww(a,da,x); + retval = (res == res + cor)? res : csloww(a,da,x); + goto ret; } else { if (a>0) {m=1;t=a;db=da;} @@ -462,7 +492,8 @@ __cos(double x) res=sn+cor; cor=(sn-res)+cor; cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps; - return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x); + retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x); + goto ret; } break; @@ -483,7 +514,8 @@ __cos(double x) res=cs+cor; cor=(cs-res)+cor; cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps; - return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n); + retval = (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n); + goto ret; break; @@ -518,7 +550,8 @@ __cos(double x) res = a+t; cor = (a-res)+t; cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps; - return (res == res + cor)? res : bsloww(a,da,x,n); + retval = (res == res + cor)? res : bsloww(a,da,x,n); + goto ret; } else { if (a>0) {m=1;t=a;db=da;} @@ -537,7 +570,8 @@ __cos(double x) res=sn+cor; cor=(sn-res)+cor; cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps; - return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n); + retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n); + goto ret; } break; @@ -558,7 +592,8 @@ __cos(double x) res=cs+cor; cor=(cs-res)+cor; cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps; - return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n); + retval = (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n); + goto ret; break; } @@ -570,17 +605,20 @@ __cos(double x) n = __branred(x,&a,&da); switch (n) { case 1: - if (a*a < 0.01588) return bsloww(-a,-da,x,n); - else return bsloww1(-a,-da,x,n); + if (a*a < 0.01588) retval = bsloww(-a,-da,x,n); + else retval = bsloww1(-a,-da,x,n); + goto ret; break; case 3: - if (a*a < 0.01588) return bsloww(a,da,x,n); - else return bsloww1(a,da,x,n); + if (a*a < 0.01588) retval = bsloww(a,da,x,n); + else retval = bsloww1(a,da,x,n); + goto ret; break; case 0: case 2: - return bsloww2(a,da,x,n); + retval = bsloww2(a,da,x,n); + goto ret; break; } @@ -592,10 +630,13 @@ __cos(double x) else { if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); - return x / x; /* |x| > 2^1024 */ + retval = x / x; /* |x| > 2^1024 */ + goto ret; } - return 0; + ret: + libc_feupdateenv (&env); + return retval; } /************************************************************************/ diff --git a/libc/sysdeps/ieee754/dbl-64/s_tan.c b/libc/sysdeps/ieee754/dbl-64/s_tan.c index 962a4eba6..2c26756ff 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_tan.c +++ b/libc/sysdeps/ieee754/dbl-64/s_tan.c @@ -39,6 +39,8 @@ #include "mpa.h" #include "MathLib.h" #include "math.h" +#include "math_private.h" +#include <fenv.h> #ifndef SECTION # define SECTION @@ -66,21 +68,27 @@ tan(double x) { mp_no mpy; #endif + fenv_t env; + double retval; + int __branred(double, double *, double *); int __mpranred(double, mp_no *, int); + libc_feholdexcept_setround (&env, FE_TONEAREST); + /* x=+-INF, x=NaN */ num.d = x; ux = num.i[HIGH_HALF]; if ((ux&0x7ff00000)==0x7ff00000) { if ((ux&0x7fffffff)==0x7ff00000) __set_errno (EDOM); - return x-x; + retval = x-x; + goto ret; } w=(x<ZERO) ? -x : x; /* (I) The case abs(x) <= 1.259e-8 */ - if (w<=g1.d) return x; + if (w<=g1.d) { retval = x; goto ret; } /* (II) The case 1.259e-8 < abs(x) <= 0.0608 */ if (w<=g2.d) { @@ -88,7 +96,7 @@ tan(double x) { /* First stage */ x2 = x*x; t2 = x*x2*(d3.d+x2*(d5.d+x2*(d7.d+x2*(d9.d+x2*d11.d)))); - if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) return y; + if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) { retval = y; goto ret; } /* Second stage */ c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+ @@ -108,8 +116,9 @@ tan(double x) { MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8) MUL2(x ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8) ADD2(x ,zero.d,c2,cc2,c1,cc1,t1,t2) - if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) return y; - return tanMp(x); + if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) { retval = y; goto ret; } + retval = tanMp(x); + goto ret; } /* (III) The case 0.0608 < abs(x) <= 0.787 */ @@ -120,10 +129,10 @@ tan(double x) { z = w-xfg[i][0].d; z2 = z*z; s = (x<ZERO) ? MONE : ONE; pz = z+z*z2*(e0.d+z2*e1.d); fi = xfg[i][1].d; gi = xfg[i][2].d; t2 = pz*(gi+fi)/(gi-pz); - if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) return (s*y); + if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) { retval = (s*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = fi*ua3.d+t3*ub3.d; - if ((y=fi+(t2-t4))==fi+(t2+t4)) return (s*y); + if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (s*y); goto ret; } /* Second stage */ ffi = xfg[i][3].d; @@ -141,8 +150,9 @@ tan(double x) { SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2) DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) return (s*y); - return tanMp(x); + if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) { retval = (s*y); goto ret; } + retval = tanMp(x); + goto ret; } /* (---) The case 0.787 < abs(x) <= 25 */ @@ -160,7 +170,7 @@ tan(double x) { else {ya= a; yya= da; sy= ONE;} /* (IV),(V) The case 0.787 < abs(x) <= 25, abs(y) <= 1e-7 */ - if (ya<=gy1.d) return tanMp(x); + if (ya<=gy1.d) { retval = tanMp(x); goto ret; } /* (VI) The case 0.787 < abs(x) <= 25, 1e-7 < abs(y) <= 0.0608 */ if (ya<=gy2.d) { @@ -170,10 +180,10 @@ tan(double x) { /* First stage -cot */ EADD(a,t2,b,db) DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) return (-y); } + if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) { retval = (-y); goto ret; } } else { /* First stage tan */ - if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) return y; } + if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) { retval = y; goto ret; } } /* Second stage */ /* Range reduction by algorithm ii */ t = (x*hpinv.d + toint.d); @@ -211,11 +221,12 @@ tan(double x) { if (n) { /* Second stage -cot */ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) return (-y); } + if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) { retval = (-y); goto ret; } } else { /* Second stage tan */ - if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) return y; } - return tanMp(x); + if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) { retval = y; goto ret; } } + retval = tanMp(x); + goto ret; } /* (VII) The case 0.787 < abs(x) <= 25, 0.0608 < abs(y) <= 0.787 */ @@ -229,17 +240,17 @@ tan(double x) { if (n) { /* -cot */ t2 = pz*(fi+gi)/(fi+pz); - if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) return (-sy*y); + if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) { retval = (-sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = gi*ua10.d+t3*ub10.d; - if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); } + if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } } else { /* tan */ t2 = pz*(gi+fi)/(gi-pz); - if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) return (sy*y); + if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) { retval = (sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = fi*ua9.d+t3*ub9.d; - if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); } + if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } } /* Second stage */ ffi = xfg[i][3].d; @@ -260,13 +271,14 @@ tan(double x) { if (n) { /* -cot */ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) return (-sy*y); } + if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) { retval = (-sy*y); goto ret; } } else { /* tan */ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) return (sy*y); } + if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) { retval = (sy*y); goto ret; } } - return tanMp(x); + retval = tanMp(x); + goto ret; } /* (---) The case 25 < abs(x) <= 1e8 */ @@ -288,7 +300,7 @@ tan(double x) { else {ya= a; yya= da; sy= ONE;} /* (+++) The case 25 < abs(x) <= 1e8, abs(y) <= 1e-7 */ - if (ya<=gy1.d) return tanMp(x); + if (ya<=gy1.d) { retval = tanMp(x); goto ret; } /* (VIII) The case 25 < abs(x) <= 1e8, 1e-7 < abs(y) <= 0.0608 */ if (ya<=gy2.d) { @@ -298,10 +310,10 @@ tan(double x) { /* First stage -cot */ EADD(a,t2,b,db) DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) return (-y); } + if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) { retval = (-y); goto ret; } } else { /* First stage tan */ - if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) return y; } + if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) { retval = y; goto ret; } } /* Second stage */ MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8) @@ -325,11 +337,12 @@ tan(double x) { if (n) { /* Second stage -cot */ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) return (-y); } + if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) { retval = (-y); goto ret; } } else { /* Second stage tan */ - if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) return (y); } - return tanMp(x); + if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) { retval = (y); goto ret; } } + retval = tanMp(x); + goto ret; } /* (IX) The case 25 < abs(x) <= 1e8, 0.0608 < abs(y) <= 0.787 */ @@ -342,17 +355,17 @@ tan(double x) { if (n) { /* -cot */ t2 = pz*(fi+gi)/(fi+pz); - if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) return (-sy*y); + if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) { retval = (-sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = gi*ua18.d+t3*ub18.d; - if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); } + if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } } else { /* tan */ t2 = pz*(gi+fi)/(gi-pz); - if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) return (sy*y); + if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) { retval = (sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = fi*ua17.d+t3*ub17.d; - if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); } + if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } } /* Second stage */ ffi = xfg[i][3].d; @@ -373,12 +386,13 @@ tan(double x) { if (n) { /* -cot */ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) return (-sy*y); } + if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) { retval = (-sy*y); goto ret; } } else { /* tan */ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) return (sy*y); } - return tanMp(x); + if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) { retval = (sy*y); goto ret; } } + retval = tanMp(x); + goto ret; } /* (---) The case 1e8 < abs(x) < 2**1024 */ @@ -389,7 +403,7 @@ tan(double x) { else {ya= a; yya= da; sy= ONE;} /* (+++) The case 1e8 < abs(x) < 2**1024, abs(y) <= 1e-7 */ - if (ya<=gy1.d) return tanMp(x); + if (ya<=gy1.d) { retval = tanMp(x); goto ret; } /* (X) The case 1e8 < abs(x) < 2**1024, 1e-7 < abs(y) <= 0.0608 */ if (ya<=gy2.d) { @@ -399,10 +413,10 @@ tan(double x) { /* First stage -cot */ EADD(a,t2,b,db) DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) return (-y); } + if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) { retval = (-y); goto ret; } } else { /* First stage tan */ - if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) return y; } + if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) { retval = y; goto ret; } } /* Second stage */ /* Reduction by algorithm iv */ @@ -431,11 +445,12 @@ tan(double x) { if (n) { /* Second stage -cot */ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) return (-y); } + if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) { retval = (-y); goto ret; } } else { /* Second stage tan */ - if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) return y; } - return tanMp(x); + if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) { retval = y; goto ret; } } + retval = tanMp(x); + goto ret; } /* (XI) The case 1e8 < abs(x) < 2**1024, 0.0608 < abs(y) <= 0.787 */ @@ -448,17 +463,17 @@ tan(double x) { if (n) { /* -cot */ t2 = pz*(fi+gi)/(fi+pz); - if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) return (-sy*y); + if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) { retval = (-sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = gi*ua26.d+t3*ub26.d; - if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); } + if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } } else { /* tan */ t2 = pz*(gi+fi)/(gi-pz); - if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) return (sy*y); + if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) { retval = (sy*y); goto ret; } t3 = (t2<ZERO) ? -t2 : t2; t4 = fi*ua25.d+t3*ub25.d; - if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); } + if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } } /* Second stage */ ffi = xfg[i][3].d; @@ -479,14 +494,18 @@ tan(double x) { if (n) { /* -cot */ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) return (-sy*y); } + if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) { retval = (-sy*y); goto ret; } } else { /* tan */ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) - if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) return (sy*y); } - return tanMp(x); -} + if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) { retval = (sy*y); goto ret; } } + retval = tanMp(x); + goto ret; + ret: + libc_feupdateenv (&env); + return retval; +} /* multiple precision stage */ /* Convert x to multi precision number,compute tan(x) by mptan() routine */ diff --git a/libc/sysdeps/ieee754/dbl-64/w_exp.c b/libc/sysdeps/ieee754/dbl-64/w_exp.c index ee42587be..b584ed83d 100644 --- a/libc/sysdeps/ieee754/dbl-64/w_exp.c +++ b/libc/sysdeps/ieee754/dbl-64/w_exp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Free Software Foundation, Inc. +/* Copyright (C) 2011, 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@gmail.com>, 2011. @@ -28,12 +28,12 @@ u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ double __exp (double x) { - if (__builtin_expect (x > o_threshold, 0)) + if (__builtin_expect (isgreater (x, o_threshold), 0)) { if (_LIB_VERSION != _IEEE_) return __kernel_standard_f (x, x, 6); } - else if (__builtin_expect (x < u_threshold, 0)) + else if (__builtin_expect (isless (x, u_threshold), 0)) { if (_LIB_VERSION != _IEEE_) return __kernel_standard_f (x, x, 7); diff --git a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c index d6b97b548..1d0da687c 100644 --- a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c +++ b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c @@ -39,11 +39,13 @@ __scalbln (double x, long int n) k = ((ix >> 52) & 0x7ff) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {INSERT_WORDS64(x,(ix&UINT64_C(0x800fffffffffffff))|(k<<52)); return x;} diff --git a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c index 7f0e21f64..e183c3875 100644 --- a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c +++ b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c @@ -39,11 +39,13 @@ __scalbn (double x, int n) k = ((ix >> 52) & 0x7ff) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {INSERT_WORDS64(x,(ix&UINT64_C(0x800fffffffffffff))|(k<<52)); return x;} |