POK
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Fri Jan 30 14:41:34 2009 00015 */ 00016 00017 /* e_hypotf.c -- float version of e_hypot.c. 00018 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 00019 */ 00020 00021 /* 00022 * ==================================================== 00023 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 00024 * 00025 * Developed at SunPro, a Sun Microsystems, Inc. business. 00026 * Permission to use, copy, modify, and distribute this 00027 * software is freely granted, provided that this notice 00028 * is preserved. 00029 * ==================================================== 00030 */ 00031 00032 #ifdef POK_NEEDS_LIBMATH 00033 00034 #include "math_private.h" 00035 00036 float 00037 __ieee754_hypotf(float x, float y) 00038 { 00039 float a=x,b=y,t1,t2,yy1,y2,w; 00040 int32_t j,k,ha,hb; 00041 00042 GET_FLOAT_WORD(ha,x); 00043 ha &= 0x7fffffff; 00044 GET_FLOAT_WORD(hb,y); 00045 hb &= 0x7fffffff; 00046 if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} 00047 SET_FLOAT_WORD(a,ha); /* a <- |a| */ 00048 SET_FLOAT_WORD(b,hb); /* b <- |b| */ 00049 if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ 00050 k=0; 00051 if(ha > 0x58800000) { /* a>2**50 */ 00052 if(ha >= 0x7f800000) { /* Inf or NaN */ 00053 w = a+b; /* for sNaN */ 00054 if(ha == 0x7f800000) w = a; 00055 if(hb == 0x7f800000) w = b; 00056 return w; 00057 } 00058 /* scale a and b by 2**-60 */ 00059 ha -= 0x5d800000; hb -= 0x5d800000; k += 60; 00060 SET_FLOAT_WORD(a,ha); 00061 SET_FLOAT_WORD(b,hb); 00062 } 00063 if(hb < 0x26800000) { /* b < 2**-50 */ 00064 if(hb <= 0x007fffff) { /* subnormal b or 0 */ 00065 if(hb==0) return a; 00066 SET_FLOAT_WORD(t1,0x3f000000); /* t1=2^126 */ 00067 b *= t1; 00068 a *= t1; 00069 k -= 126; 00070 } else { /* scale a and b by 2^60 */ 00071 ha += 0x5d800000; /* a *= 2^60 */ 00072 hb += 0x5d800000; /* b *= 2^60 */ 00073 k -= 60; 00074 SET_FLOAT_WORD(a,ha); 00075 SET_FLOAT_WORD(b,hb); 00076 } 00077 } 00078 /* medium size a and b */ 00079 w = a-b; 00080 if (w>b) { 00081 SET_FLOAT_WORD(t1,ha&0xfffff000); 00082 t2 = a-t1; 00083 w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); 00084 } else { 00085 a = a+a; 00086 SET_FLOAT_WORD(yy1,hb&0xfffff000); 00087 y2 = b - yy1; 00088 SET_FLOAT_WORD(t1,ha+0x00800000); 00089 t2 = a - t1; 00090 w = __ieee754_sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b))); 00091 } 00092 if(k!=0) { 00093 SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); 00094 return t1*w; 00095 } else return w; 00096 } 00097 #endif 00098