POK
e_logf.c
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Fri Jan 30 14:41:34 2009
15  */
16 
17 /* e_logf.c -- float version of e_log.c.
18  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
19  */
20 
21 /*
22  * ====================================================
23  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
24  *
25  * Developed at SunPro, a Sun Microsystems, Inc. business.
26  * Permission to use, copy, modify, and distribute this
27  * software is freely granted, provided that this notice
28  * is preserved.
29  * ====================================================
30  */
31 
32 #ifdef POK_NEEDS_LIBMATH
33 
34 #include "math_private.h"
35 
36 static const float
37 ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
38 ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
39 two25 = 3.355443200e+07, /* 0x4c000000 */
40 Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
41 Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
42 Lg3 = 2.8571429849e-01, /* 3E924925 */
43 Lg4 = 2.2222198546e-01, /* 3E638E29 */
44 Lg5 = 1.8183572590e-01, /* 3E3A3325 */
45 Lg6 = 1.5313838422e-01, /* 3E1CD04F */
46 Lg7 = 1.4798198640e-01; /* 3E178897 */
47 
48 static const float zero = 0.0;
49 
50 float
51 __ieee754_logf(float x)
52 {
53  float hfsq,f,s,z,R,w,t1,t2,dk;
54  int32_t k,ix,i,j;
55 
56  GET_FLOAT_WORD(ix,x);
57 
58  k=0;
59  if (ix < 0x00800000) { /* x < 2**-126 */
60  if ((ix&0x7fffffff)==0)
61  return -two25/zero; /* log(+-0)=-inf */
62  if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
63  k -= 25; x *= two25; /* subnormal number, scale up x */
64  GET_FLOAT_WORD(ix,x);
65  }
66  if (ix >= 0x7f800000) return x+x;
67  k += (ix>>23)-127;
68  ix &= 0x007fffff;
69  i = (ix+(0x95f64<<3))&0x800000;
70  SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
71  k += (i>>23);
72  f = x-(float)1.0;
73  if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
74  if(f==zero) { if(k==0) return zero; else {dk=(float)k;
75  return dk*ln2_hi+dk*ln2_lo;}
76  }
77  R = f*f*((float)0.5-(float)0.33333333333333333*f);
78  if(k==0) return f-R; else {dk=(float)k;
79  return dk*ln2_hi-((R-dk*ln2_lo)-f);}
80  }
81  s = f/((float)2.0+f);
82  dk = (float)k;
83  z = s*s;
84  i = ix-(0x6147a<<3);
85  w = z*z;
86  j = (0x6b851<<3)-ix;
87  t1= w*(Lg2+w*(Lg4+w*Lg6));
88  t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
89  i |= j;
90  R = t2+t1;
91  if(i>0) {
92  hfsq=(float)0.5*f*f;
93  if(k==0) return f-(hfsq-s*(hfsq+R)); else
94  return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
95  } else {
96  if(k==0) return f-s*(f-R); else
97  return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
98  }
99 }
100 
101 #endif
102