Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / pic / libm / expf.c
1 /*  expf.c: Computes e**x of a 32-bit float as outlined in [1]
2
3     Copyright (C) 2001, 2002  Jesus Calvino-Fraga, jesusc@ieee.org 
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
18
19 /* [1] William James Cody and W.  M.  Waite.  _Software manual for the
20    elementary functions_, Englewood Cliffs, N.J.:Prentice-Hall, 1980. */
21
22 /* Version 1.0 - Initial release */
23
24 /*
25 ** $Id: expf.c 4776 2007-04-29 13:15:51Z borutr $
26 */
27
28 #include <math.h>
29 #include <errno.h>
30
31 #define P0      0.2499999995E+0
32 #define P1      0.4160288626E-2
33 #define Q0      0.5000000000E+0
34 #define Q1      0.4998717877E-1
35
36 #define P(z) ((P1*z)+P0)
37 #define Q(z) ((Q1*z)+Q0)
38
39 #define C1       0.693359375
40 #define C2      -2.1219444005469058277e-4
41
42 #define BIGX    88.72283911  /* ln(XMAX) */
43 #define EXPEPS  1.0E-7       /* exp(1.0E-7)=0.0000001 */
44 #define K1      1.4426950409 /* 1/ln(2) */
45
46 float expf(const float x)
47 {
48     int n;
49     float xn, g, r, z, y;
50     char sign;
51
52     if(x>=0.0)
53         { y=x;  sign=0; }
54     else
55         { y=-x; sign=1; }
56
57     if(y<EXPEPS) return 1.0;
58
59     if(y>BIGX)
60     {
61         if(sign)
62         {
63             errno=ERANGE;
64             return XMAX;
65         }
66         else
67         {
68             return 0.0;
69         }
70     }
71
72     z=y*K1;
73     n=z;
74
75     if(n<0) --n;
76     if(z-n>=0.5) ++n;
77     xn=n;
78     g=((y-xn*C1))-xn*C2;
79     z=g*g;
80     r=P(z)*g;
81     r=0.5+(r/(Q(z)-r));
82
83     n++;
84     z=ldexpf(r, n);
85     if(sign)
86         return 1.0/z;
87     else
88         return z;
89 }
90