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 /* s_atanf.c -- float version of s_atan.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 <types.h> 00035 #include <libm.h> 00036 #include "math_private.h" 00037 00038 static const float atanhi[] = { 00039 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ 00040 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ 00041 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ 00042 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ 00043 }; 00044 00045 static const float atanlo[] = { 00046 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ 00047 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ 00048 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ 00049 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ 00050 }; 00051 00052 static const float aT[] = { 00053 3.3333334327e-01, /* 0x3eaaaaaa */ 00054 -2.0000000298e-01, /* 0xbe4ccccd */ 00055 1.4285714924e-01, /* 0x3e124925 */ 00056 -1.1111110449e-01, /* 0xbde38e38 */ 00057 9.0908870101e-02, /* 0x3dba2e6e */ 00058 -7.6918758452e-02, /* 0xbd9d8795 */ 00059 6.6610731184e-02, /* 0x3d886b35 */ 00060 -5.8335702866e-02, /* 0xbd6ef16b */ 00061 4.9768779427e-02, /* 0x3d4bda59 */ 00062 -3.6531571299e-02, /* 0xbd15a221 */ 00063 1.6285819933e-02, /* 0x3c8569d7 */ 00064 }; 00065 00066 static const float 00067 one = 1.0, 00068 huge = 1.0e30; 00069 00070 float 00071 atanf(float x) 00072 { 00073 float w,s1,s2,z; 00074 int32_t ix,hx,id; 00075 00076 GET_FLOAT_WORD(hx,x); 00077 ix = hx&0x7fffffff; 00078 if(ix>=0x50800000) { /* if |x| >= 2^34 */ 00079 if(ix>0x7f800000) 00080 return x+x; /* NaN */ 00081 if(hx>0) return atanhi[3]+atanlo[3]; 00082 else return -atanhi[3]-atanlo[3]; 00083 } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ 00084 if (ix < 0x31000000) { /* |x| < 2^-29 */ 00085 if(huge+x>one) return x; /* raise inexact */ 00086 } 00087 id = -1; 00088 } else { 00089 x = fabsf(x); 00090 if (ix < 0x3f980000) { /* |x| < 1.1875 */ 00091 if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ 00092 id = 0; x = ((float)2.0*x-one)/((float)2.0+x); 00093 } else { /* 11/16<=|x|< 19/16 */ 00094 id = 1; x = (x-one)/(x+one); 00095 } 00096 } else { 00097 if (ix < 0x401c0000) { /* |x| < 2.4375 */ 00098 id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); 00099 } else { /* 2.4375 <= |x| < 2^66 */ 00100 id = 3; x = -(float)1.0/x; 00101 } 00102 }} 00103 /* end of argument reduction */ 00104 z = x*x; 00105 w = z*z; 00106 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ 00107 s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); 00108 s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); 00109 if (id<0) return x - x*(s1+s2); 00110 else { 00111 z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); 00112 return (hx<0)? -z:z; 00113 } 00114 } 00115 00116 #endif