POK
e_log2f.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 = 0.6931471805599452862268,
38 two25 = 3.355443200e+07, /* 0x4c000000 */
39 Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
40 Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
41 Lg3 = 2.8571429849e-01, /* 3E924925 */
42 Lg4 = 2.2222198546e-01, /* 3E638E29 */
43 Lg5 = 1.8183572590e-01, /* 3E3A3325 */
44 Lg6 = 1.5313838422e-01, /* 3E1CD04F */
45 Lg7 = 1.4798198640e-01; /* 3E178897 */
46 
47 static const float zero = 0.0;
48 
49 float
50 __ieee754_log2f(float x)
51 {
52  float hfsq,f,s,z,R,w,t1,t2,dk;
53  int32_t k,ix,i,j;
54 
55  GET_FLOAT_WORD(ix,x);
56 
57  k=0;
58  if (ix < 0x00800000) { /* x < 2**-126 */
59  if ((ix&0x7fffffff)==0)
60  return -two25/zero; /* log(+-0)=-inf */
61  if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
62  k -= 25; x *= two25; /* subnormal number, scale up x */
63  GET_FLOAT_WORD(ix,x);
64  }
65  if (ix >= 0x7f800000) return x+x;
66  k += (ix>>23)-127;
67  ix &= 0x007fffff;
68  i = (ix+(0x95f64<<3))&0x800000;
69  SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
70  k += (i>>23);
71  dk = (float)k;
72  f = x-(float)1.0;
73  if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
74  if (f==zero)
75  return (dk);
76  R = f*f*((float)0.5-(float)0.33333333333333333*f);
77  return (dk-(R-f)/ln2);
78  }
79  s = f/((float)2.0+f);
80  z = s*s;
81  i = ix-(0x6147a<<3);
82  w = z*z;
83  j = (0x6b851<<3)-ix;
84  t1= w*(Lg2+w*(Lg4+w*Lg6));
85  t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
86  i |= j;
87  R = t2+t1;
88  if(i>0) {
89  hfsq=(float)0.5*f*f;
90  return (dk-(hfsq-s*(hfsq+R)-f)/ln2);
91  } else
92  return (dk-((s*(f-R))-f)/ln2);
93 }
94 #endif