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.logf.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
00076 #if defined(mips) && !defined(__GNUC__)
00077 extern float flog(float);
00078 extern float logf(float);
00079
00080 #pragma weak flog = __logf
00081 #pragma weak logf = __logf
00082 #endif
00083
00084 #if defined(BUILD_OS_DARWIN)
00085 extern float __logf(float);
00086 #pragma weak logf
00087 float logf( float x ) {
00088 return __logf( x );
00089 }
00090 #elif defined(__GNUC__)
00091 extern float __logf(float);
00092 float logf(float) __attribute__ ((weak, alias ("__logf")));
00093 #endif
00094
00095 extern const fu _logftabhi[];
00096 extern const fu _logftablo[];
00097
00098 static const fu Qnan = {QNANF};
00099
00100 static const fu Neginf = {0xff800000};
00101
00102 static const fu Inf = {0x7f800000};
00103
00104 static const fu P[] =
00105 {
00106 {0x3f800000},
00107 {0x3daaaaa9},
00108 {0x3c4dffbb},
00109 };
00110
00111 static const fu Q[] =
00112 {
00113 {0x3f800000},
00114 {0x3daaaac2},
00115 };
00116
00117 static const fu log2_lead = {0x3f317200};
00118
00119 static const fu log2_trail = {0x35bfbe8e};
00120
00121 static const fu f_one = {0x3f800000};
00122
00123 static const fu Scaleup = {0x4b000000};
00124
00125
00126
00127 static const int lim1 = {0x3f707d5f};
00128
00129
00130
00131 static const int lim2 = {0x3f88415b};
00132
00133 static const int one = {0x3f800000};
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 float
00146 __logf( float x )
00147 {
00148 int ix;
00149 int j, m;
00150 float u, v;
00151 float result;
00152 float f, F;
00153 float l_lead, l_trail;
00154 float q;
00155 float md;
00156 double u1;
00157 #ifdef _CALL_MATHERR
00158 struct exception exstruct;
00159 #endif
00160
00161 FLT2INT(x, ix);
00162 m = (ix >> MANTWIDTH);
00163
00164 if ( (0 < m) && (m < 0xff) )
00165 {
00166
00167
00168 if ( (ix >= lim2) || (ix <= lim1) )
00169 {
00170
00171 m -= EXPBIAS;
00172 L:
00173 ix &= EXPMASK;
00174 ix |= 0x43000000;
00175 INT2FLT(ix, x);
00176
00177 j = ROUNDF(x);
00178
00179 F = j;
00180 j -= 128;
00181
00182 f = x - F;
00183
00184 md = m;
00185
00186 u = (f + f)/(x + F);
00187
00188 l_lead = md*log2_lead.f;
00189 l_trail = md*log2_trail.f;
00190
00191 l_lead += _logftabhi[j].f;
00192 l_trail += _logftablo[j].f;
00193
00194 v = u*u;
00195
00196 q = Q[1].f*(v*u);
00197
00198 result = l_lead + (u + (q + l_trail));
00199
00200 return ( result );
00201
00202 }
00203
00204 if ( ix == one )
00205 return ( 0.0f );
00206
00207 x = x - f_one.f;
00208
00209 u1 = x/(2.0 + x);
00210 u1 = u1 + u1;
00211 u = u1;
00212 v = u1*u1;
00213
00214 q = (P[2].f*v + P[1].f)*(v*u);
00215
00216 result = u1 + q;
00217
00218 return ( result );
00219 }
00220
00221 if ( x != x )
00222 {
00223
00224
00225 #ifdef _CALL_MATHERR
00226
00227 exstruct.type = DOMAIN;
00228 exstruct.name = "logf";
00229 exstruct.arg1 = x;
00230 exstruct.retval = Qnan.f;
00231
00232 if ( matherr( &exstruct ) == 0 )
00233 {
00234 fprintf(stderr, "domain error in logf\n");
00235 SETERRNO(EDOM);
00236 }
00237
00238 return ( exstruct.retval );
00239 #else
00240 NAN_SETERRNO(EDOM);
00241
00242 return ( Qnan.f );
00243 #endif
00244 }
00245
00246 if ( x == Inf.f )
00247 {
00248 SETERRNO(EDOM);
00249
00250 return ( Inf.f );
00251 }
00252
00253 if ( x == 0.0f )
00254 {
00255 zeroarg:
00256
00257 #ifdef _CALL_MATHERR
00258
00259 exstruct.type = OVERFLOW;
00260 exstruct.name = "logf";
00261 exstruct.arg1 = x;
00262 exstruct.retval = Neginf.f;
00263
00264 if ( matherr( &exstruct ) == 0 )
00265 {
00266 fprintf(stderr, "overflow range error in logf\n");
00267 SETERRNO(ERANGE);
00268 }
00269
00270 return ( exstruct.retval );
00271 #else
00272 SETERRNO(ERANGE);
00273
00274 return ( Neginf.f );
00275 #endif
00276 }
00277
00278 if ( x < 0.0f )
00279 {
00280 #ifdef _CALL_MATHERR
00281
00282 exstruct.type = DOMAIN;
00283 exstruct.name = "logf";
00284 exstruct.arg1 = x;
00285 exstruct.retval = Qnan.f;
00286
00287 if ( matherr( &exstruct ) == 0 )
00288 {
00289 fprintf(stderr, "domain error in logf\n");
00290 SETERRNO(EDOM);
00291 }
00292
00293 return ( exstruct.retval );
00294 #else
00295 SETERRNO(EDOM);
00296
00297 return ( Qnan.f );
00298 #endif
00299 }
00300
00301
00302
00303
00304
00305 x *= Scaleup.f;
00306
00307 if ( x == 0.0f )
00308 goto zeroarg;
00309
00310 FLT2INT(x, ix);
00311 m = (ix >> MANTWIDTH);
00312 m -= EXPBIAS;
00313 m -= 23;
00314 goto L;
00315 }
00316