00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/libm/mips/SCCS/s.tanh.c $ $Revision: 1.5 $";
00060
00061 #ifdef _CALL_MATHERR
00062 #include <stdio.h>
00063 #include <math.h>
00064 #include <errno.h>
00065 #endif
00066
00067 #include "libm.h"
00068
00069 #if defined(mips) && !defined(__GNUC__)
00070 extern double tanh(double);
00071
00072 #pragma weak tanh = __tanh
00073 #endif
00074
00075 #if defined(BUILD_OS_DARWIN)
00076 extern double __tanh(double);
00077 #pragma weak tanh
00078 double tanh( double x ) {
00079 return __tanh( x );
00080 }
00081 #elif defined(__GNUC__)
00082 extern double __tanh(double);
00083
00084 double tanh() __attribute__ ((weak, alias ("__tanh")));
00085
00086 #endif
00087
00088 extern const du _exptabhi[];
00089 extern const du _exptablo[];
00090
00091 static const du Qnan =
00092 {D(QNANHI, QNANLO)};
00093
00094 static const du rln2by32 =
00095 {D(0x40471547, 0x652b82fe)};
00096
00097 static const du ln2by32hi =
00098 {D(0x3f962e42, 0xfef00000)};
00099
00100 static const du ln2by32lo =
00101 {D(0x3d8473de, 0x6af278ed)};
00102
00103 static const du one =
00104 {D(0x3ff00000, 0x00000000)};
00105
00106 static const du m_one =
00107 {D(0xbff00000, 0x00000000)};
00108
00109
00110
00111 static const du P[] =
00112 {
00113 {D(0x3ff00000, 0x00000000)},
00114 {D(0x3ff00000, 0x00000000)},
00115 {D(0x3fe00000, 0x00000000)},
00116 {D(0x3fc55555, 0x55548f7c)},
00117 {D(0x3fa55555, 0x55545d4e)},
00118 {D(0x3f811115, 0xb7aa905e)},
00119 {D(0x3f56c172, 0x8d739765)},
00120 };
00121
00122
00123
00124 static const du a[] =
00125 {
00126 {D(0xc099355d, 0x63ff6958)},
00127 {D(0xc058ce3d, 0x86e94fd8)},
00128 {D(0xbfeedc25, 0xfda04bc9)},
00129 };
00130
00131 static const du b[] =
00132 {
00133 {D(0x40b2e806, 0x0aff8f02)},
00134 {D(0x40a1735a, 0x9a3f1e85)},
00135 {D(0x405c2f6d, 0x1c260d6d)},
00136 };
00137
00138 static const du bigarg =
00139 {D(0x40330fc1, 0x931f09c9)};
00140
00141 static const du m_bigarg =
00142 {D(0xc0330fc1, 0x931f09c9)};
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 double
00155 __tanh( x )
00156 double x;
00157 {
00158 #ifdef _32BIT_MACHINE
00159
00160 int ix, xpt;
00161 int l;
00162
00163 #else
00164
00165 long long ix, xpt;
00166 long long l;
00167
00168 #endif
00169
00170 int n, m, j;
00171 double absx, xsq;
00172 double y1, y2, y;
00173 double p, q;
00174 double nd;
00175 double s, s_lead, s_trail;
00176 double result;
00177 double twopm;
00178 double num, denom;
00179 #ifdef _CALL_MATHERR
00180 struct exception exstruct;
00181 #endif
00182
00183
00184
00185 #ifdef _32BIT_MACHINE
00186
00187 DBLHI2INT(x, ix);
00188 #else
00189 DBL2LL(x, ix);
00190 #endif
00191 xpt = (ix >> DMANTWIDTH);
00192 xpt &= 0x7ff;
00193
00194 if ( xpt < 0x403 )
00195 {
00196
00197
00198 if ( xpt >= 0x3fe )
00199 {
00200
00201 L:
00202 absx = fabs(x);
00203 absx += absx;
00204
00205
00206
00207 nd = absx*rln2by32.d;
00208 n = ROUND(nd);
00209 nd = n;
00210
00211 y1 = absx - nd*ln2by32hi.d;
00212 y2 = nd*ln2by32lo.d;
00213 y = y1 - y2;
00214
00215 j = n & 0x1f;
00216 m = n >> 5;
00217
00218 s_lead = _exptabhi[j].d;
00219 s_trail = _exptablo[j].d;
00220 s = s_lead + s_trail;
00221
00222 q = ((((P[6].d*y + P[5].d)*y + P[4].d)*y + P[3].d)*y +
00223 P[2].d)*(y*y);
00224
00225 p = (q - y2) + y1;
00226
00227 l = m + DEXPBIAS;
00228 l <<= DMANTWIDTH;
00229
00230 #ifdef _32BIT_MACHINE
00231
00232 twopm = 0.0;
00233 INT2DBLHI(l, twopm);
00234 #else
00235 LL2DBL(l, twopm);
00236 #endif
00237 result = s_lead + (s_trail + s*p);
00238 result *= twopm;
00239
00240 result = 1.0 - 2.0/(result + 1.0);
00241
00242 if ( x < 0.0 )
00243 result = -result;
00244
00245 return ( result );
00246 }
00247
00248 if ( xpt >= 0x3e3 )
00249 {
00250
00251
00252 xsq = x*x;
00253
00254 num = (a[2].d*xsq + a[1].d)*xsq + a[0].d;
00255 denom = ((xsq + b[2].d)*xsq + b[1].d)*xsq + b[0].d;
00256
00257 return ( x + x*((xsq*num)/denom) );
00258 }
00259
00260 return ( x );
00261 }
00262
00263 if ( x != x )
00264 {
00265
00266
00267 #ifdef _CALL_MATHERR
00268
00269 exstruct.type = DOMAIN;
00270 exstruct.name = "tanh";
00271 exstruct.arg1 = x;
00272 exstruct.retval = Qnan.d;
00273
00274 if ( matherr( &exstruct ) == 0 )
00275 {
00276 fprintf(stderr, "domain error in tanh\n");
00277 SETERRNO(EDOM);
00278 }
00279
00280 return ( exstruct.retval );
00281 #else
00282 NAN_SETERRNO(EDOM);
00283
00284 return ( Qnan.d );
00285 #endif
00286 }
00287
00288 if ( x > bigarg.d )
00289 return ( one.d );
00290
00291 if ( x < m_bigarg.d )
00292 return ( m_one.d );
00293
00294 goto L;
00295
00296 }
00297
00298 #ifdef NO_LONG_DOUBLE
00299
00300 #if defined(BUILD_OS_DARWIN)
00301 extern long double __tanhl(long double);
00302 long double tanhl( long double x ) {
00303 return ( (long double)__tanh((double)x) );
00304 }
00305 #elif defined(__GNUC__)
00306 extern long double __tanhl(long double);
00307
00308 long double tanhl() __attribute__ ((weak, alias ("__tanhl")));
00309
00310 #endif
00311
00312 long double
00313 __tanhl( long double x )
00314 {
00315 return ( (long double)__tanh((double)x) );
00316 }
00317
00318 #endif
00319