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.hypot.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 hypot(double, double);
00071
00072 #pragma weak hypot = __hypot
00073 #endif
00074
00075 #if defined(BUILD_OS_DARWIN)
00076 extern double __hypot(double, double);
00077 #pragma weak hypot
00078 double hypot( double arg1, double arg2) {
00079 return __hypot( arg1, arg2 );
00080 }
00081 #elif defined(__GNUC__)
00082 extern double __hypot(double, double);
00083
00084 double hypot() __attribute__ ((weak, alias ("__hypot")));
00085
00086 #endif
00087
00088 static const du Qnan =
00089 {D(QNANHI, QNANLO)};
00090
00091 static const du Inf =
00092 {D(0x7ff00000, 0x00000000)};
00093
00094 static const du halfmaxdbl =
00095 {D(0x7fdfffff, 0xffffffff)};
00096
00097 static const du twop86 =
00098 {D(0x45500000, 0x00000000)};
00099
00100 static const du twopm86 =
00101 {D(0x3a900000, 0x00000000)};
00102
00103 static const du half =
00104 {D(0x3fe00000, 0x00000000)};
00105
00106 static const du one =
00107 {D(0x3ff00000, 0x00000000)};
00108
00109 static const du two =
00110 {D(0x40000000, 0x00000000)};
00111
00112 static const du sqrt2 =
00113 {D(0x3ff6a09e, 0x667f3bcd)};
00114
00115 static const du r2p1hi =
00116 {D(0x4003504f, 0x333f9de6)};
00117
00118 static const du r2p1lo =
00119 {D(0x3ca21165, 0xf626cdd5)};
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 double
00132 __hypot( arg1, arg2 )
00133 double arg1, arg2;
00134 {
00135 #ifdef _32BIT_MACHINE
00136
00137 int ix, iy;
00138 int xptx, xpty;
00139 int itmp;
00140
00141 #else
00142
00143 long long ix, iy;
00144 long long xptx, xpty;
00145 long long itmp;
00146
00147 #endif
00148
00149 double x, y;
00150 double tmp, q;
00151 double d, p, s, w;
00152 double result;
00153 #ifdef _CALL_MATHERR
00154 struct exception exstruct;
00155 #endif
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 #ifdef _32BIT_MACHINE
00166
00167 DBLHI2INT(arg1, ix);
00168 DBLHI2INT(arg2, iy);
00169 #else
00170 DBL2LL(arg1, ix);
00171 DBL2LL(arg2, iy);
00172 #endif
00173
00174 xptx = (ix >> DMANTWIDTH);
00175 xptx &= 0x7ff;
00176
00177 xpty = (iy >> DMANTWIDTH);
00178 xpty &= 0x7ff;
00179
00180 if ( (xptx < 0x7ff) && (xpty < 0x7ff) )
00181 {
00182 x = fabs(arg1);
00183 y = fabs(arg2);
00184
00185
00186
00187 if ( x < y )
00188 {
00189 tmp = x;
00190 x = y;
00191 y = tmp;
00192
00193 itmp = xptx;
00194 xptx = xpty;
00195 xpty = itmp;
00196 }
00197
00198 if ( xptx >= xpty + 31 )
00199 return ( x );
00200
00201 if ( y == 0.0 )
00202 return ( x );
00203
00204 if ( x > halfmaxdbl.d )
00205 {
00206
00207
00208 x *= half.d;
00209 y *= half.d;
00210
00211 if ( two.d*y < x )
00212 {
00213 q = x/y;
00214
00215 result = x + y/(sqrt(one.d + q*q) + q);
00216 }
00217 else
00218 {
00219 d = x - y;
00220 q = d/y;
00221 p = q*(two.d + q);
00222 s = sqrt(two.d + p);
00223 w = p/(s + sqrt2.d);
00224 w = q + w + r2p1lo.d + r2p1hi.d;
00225 result = x + y/w;
00226 }
00227
00228
00229
00230
00231
00232
00233 if ( result > halfmaxdbl.d )
00234 {
00235 #ifdef _CALL_MATHERR
00236
00237 exstruct.type = OVERFLOW;
00238 exstruct.name = "hypot";
00239 exstruct.arg1 = arg1;
00240 exstruct.arg2 = arg2;
00241 exstruct.retval = Inf.d;
00242
00243 if ( matherr( &exstruct ) == 0 )
00244 {
00245 fprintf(stderr, "overflow range error in hypot\n");
00246 SETERRNO(ERANGE);
00247 }
00248
00249 return ( exstruct.retval );
00250 #else
00251 SETERRNO(ERANGE);
00252
00253 return ( Inf.d );
00254 #endif
00255 }
00256 else
00257 {
00258 return ( two.d*result );
00259 }
00260 }
00261 else if ( xpty < 33 )
00262 {
00263
00264
00265 x *= twop86.d;
00266 y *= twop86.d;
00267
00268 if ( two.d*y < x )
00269 {
00270 q = x/y;
00271
00272 result = x + y/(sqrt(one.d + q*q) + q);
00273 }
00274 else
00275 {
00276 d = x - y;
00277 q = d/y;
00278 p = q*(two.d + q);
00279 s = sqrt(two.d + p);
00280 w = p/(s + sqrt2.d);
00281 w = q + w + r2p1lo.d + r2p1hi.d;
00282 result = x + y/w;
00283 }
00284
00285 result *= twopm86.d;
00286
00287 return ( result );
00288 }
00289 else
00290 {
00291 if ( two.d*y < x )
00292 {
00293 q = x/y;
00294
00295 result = x + y/(sqrt(one.d + q*q) + q);
00296 }
00297 else
00298 {
00299
00300 d = x - y;
00301 q = d/y;
00302 p = q*(two.d + q);
00303 s = sqrt(two.d + p);
00304 w = p/(s + sqrt2.d);
00305 w = q + w + r2p1lo.d + r2p1hi.d;
00306 result = x + y/w;
00307 }
00308
00309 return ( result );
00310 }
00311 }
00312
00313
00314
00315 if ( (fabs(arg1) == Inf.d) || (fabs(arg2) == Inf.d) )
00316 {
00317
00318
00319 return ( Inf.d );
00320 }
00321
00322
00323
00324 #ifdef _CALL_MATHERR
00325
00326 exstruct.type = DOMAIN;
00327 exstruct.name = "hypot";
00328 exstruct.arg1 = arg1;
00329 exstruct.arg2 = arg2;
00330 exstruct.retval = Qnan.d;
00331
00332 if ( matherr( &exstruct ) == 0 )
00333 {
00334 fprintf(stderr, "domain error in hypot\n");
00335 SETERRNO(EDOM);
00336 }
00337
00338 return ( exstruct.retval );
00339 #else
00340 NAN_SETERRNO(EDOM);
00341
00342 return ( Qnan.d );
00343 #endif
00344 }
00345
00346 #ifdef NO_LONG_DOUBLE
00347
00348 #if defined(BUILD_OS_DARWIN)
00349 extern long double __hypotl(long double, long double);
00350 long double hypotl( long double arg1, long double arg2) {
00351 return ( (long double)__hypot((double)arg1, (double)arg2) );
00352 }
00353 #elif defined(__GNUC__)
00354 extern long double __hypotl(long double, long double);
00355 long double hypotl() __attribute__ ((weak, alias ("__hypotl")));
00356
00357 #endif
00358
00359 long double
00360 __hypotl( arg1, arg2 )
00361 long double arg1, arg2;
00362 {
00363 return ( (long double)__hypot((double)arg1, (double)arg2) );
00364 }
00365
00366 #endif
00367