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.expf.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
00070
00071
00072
00073
00074
00075 #if defined(mips) && !defined(__GNUC__)
00076 extern float fexp(float);
00077 extern float expf(float);
00078
00079 #pragma weak fexp = __expf
00080 #pragma weak expf = __expf
00081 #endif
00082
00083 #if defined(BUILD_OS_DARWIN)
00084 extern float __expf(float);
00085 #pragma weak expf
00086 float expf( float x ) {
00087 return __expf( x );
00088 }
00089 #elif defined(__GNUC__)
00090 extern float __expf(float);
00091 float expf(float) __attribute__ ((weak, alias ("__expf")));
00092 #endif
00093
00094 extern const du _expftab[];
00095
00096
00097
00098 static const du P[] =
00099 {
00100 {D(0x3ff00000, 0x00000000)},
00101 {D(0x3ff00000, 0x00000000)},
00102 {D(0x3fe00008, 0x745da559)},
00103 {D(0x3fc55569, 0x9fd0029e)},
00104 };
00105
00106 static const du rln2by32 =
00107 {D(0x40471547, 0x652b82fe)};
00108
00109 static const du ln2by32hi =
00110 {D(0x3f962e42, 0xfef00000)};
00111
00112 static const du ln2by32lo =
00113 {D(0x3d8473de, 0x6af278ed)};
00114
00115 static const fu Qnan = {QNANF};
00116
00117 static const fu Inf = {0x7f800000};
00118
00119 static const fu f_one = {0x3f800000};
00120
00121 static const fu Ulimit = {0x42b17217};
00122
00123 static const fu Llimit = {0xc2cff1b4};
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 float
00136 __expf( float x )
00137 {
00138 #ifdef _32BIT_MACHINE
00139
00140 int l;
00141
00142 #else
00143
00144 long long l;
00145
00146 #endif
00147
00148 int ix, xp, j, m, n;
00149 double twopm;
00150 double result, nd, y;
00151 double s;
00152 double dx;
00153 double poly;
00154 #ifdef _CALL_MATHERR
00155 struct exception exstruct;
00156 #endif
00157
00158
00159
00160 FLT2INT(x, ix);
00161 xp = (ix >> MANTWIDTH);
00162 xp &= 0xff;
00163
00164 if ( xp < 0x85 )
00165 {
00166
00167
00168 if ( xp >= 0x66 )
00169 {
00170
00171 L:
00172 dx = x;
00173
00174
00175
00176 nd = dx*rln2by32.d;
00177 n = ROUND(nd);
00178 nd = n;
00179
00180 y = x - nd*ln2by32hi.d - nd*ln2by32lo.d;
00181
00182 j = n & 0x1f;
00183 m = n >> 5;
00184
00185 s = _expftab[j].d;
00186
00187 poly = (P[3].d*y + P[2].d)*(y*y) + y;
00188
00189 l = m + DEXPBIAS;
00190 l <<= DMANTWIDTH;
00191
00192 #ifdef _32BIT_MACHINE
00193
00194 twopm = 0.0;
00195 INT2DBLHI(l, twopm);
00196 #else
00197 LL2DBL(l, twopm);
00198 #endif
00199 result = s + s*poly;
00200 result *= twopm;
00201
00202 return ( (float)result );
00203 }
00204
00205 return ( f_one.f + x );
00206 }
00207
00208 if ( x != x )
00209 {
00210
00211
00212 #ifdef _CALL_MATHERR
00213
00214 exstruct.type = DOMAIN;
00215 exstruct.name = "expf";
00216 exstruct.arg1 = x;
00217 exstruct.retval = Qnan.f;
00218
00219 if ( matherr( &exstruct ) == 0 )
00220 {
00221 fprintf(stderr, "domain error in expf\n");
00222 SETERRNO(EDOM);
00223 }
00224
00225 return ( exstruct.retval );
00226 #else
00227 NAN_SETERRNO(EDOM);
00228
00229 return ( Qnan.f );
00230 #endif
00231 }
00232
00233 if ( x > Ulimit.f )
00234 {
00235 #ifdef _CALL_MATHERR
00236
00237 exstruct.type = OVERFLOW;
00238 exstruct.name = "expf";
00239 exstruct.arg1 = x;
00240 exstruct.retval = Inf.f;
00241
00242 if ( matherr( &exstruct ) == 0 )
00243 {
00244 fprintf(stderr, "overflow error in expf\n");
00245 SETERRNO(ERANGE);
00246 }
00247
00248 return ( exstruct.retval );
00249 #else
00250 SETERRNO(ERANGE);
00251
00252 return ( Inf.f );
00253 #endif
00254 }
00255
00256 if ( x < Llimit.f )
00257 {
00258 #ifdef _CALL_MATHERR
00259
00260 exstruct.type = UNDERFLOW;
00261 exstruct.name = "expf";
00262 exstruct.arg1 = x;
00263 exstruct.retval = 0.0;
00264
00265 if ( matherr( &exstruct ) == 0 )
00266 {
00267 fprintf(stderr, "underflow error in expf\n");
00268 SETERRNO(ERANGE);
00269 }
00270
00271 return ( exstruct.retval );
00272 #else
00273 SETERRNO(ERANGE);
00274
00275 return ( 0.0f );
00276 #endif
00277 }
00278
00279 goto L;
00280 }
00281