* src/port.h: made reset_regparms prototype void parameter explicit.
[fw/sdcc] / device / lib / 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 #include <math.h>
25 #include <errno.h>
26 #include <stdbool.h>
27
28 #define P0      0.2499999995E+0
29 #define P1      0.4160288626E-2
30 #define Q0      0.5000000000E+0
31 #define Q1      0.4998717877E-1
32
33 #define P(z) ((P1*z)+P0)
34 #define Q(z) ((Q1*z)+Q0)
35
36 #define C1       0.693359375
37 #define C2      -2.1219444005469058277e-4
38
39 #define BIGX    88.72283911  /* ln(XMAX) */
40 #define EXPEPS  1.0E-7       /* exp(1.0E-7)=0.0000001 */
41 #define K1      1.4426950409 /* 1/ln(2) */
42
43 float expf(const float x)
44 {
45     int n;
46     float xn, g, r, z, y;
47         BOOL sign;
48
49     if(x>=0.0)
50         { y=x;  sign=0; }
51     else
52         { y=-x; sign=1; }
53
54     if(y<EXPEPS) return 1.0;
55
56     if(y>BIGX)
57     {
58         if(sign)
59         {
60             errno=ERANGE;
61             return XMAX;
62         }
63         else
64         {
65             return 0.0;
66         }
67     }
68
69     z=y*K1;
70     n=z;
71
72     if(n<0) --n;
73     if(z-n>=0.5) ++n;
74     xn=n;
75     g=((y-xn*C1))-xn*C2;
76     z=g*g;
77     r=P(z)*g;
78     r=0.5+(r/(Q(z)-r));
79
80     n++;
81     z=ldexpf(r, n);
82     if(sign)
83         return 1.0/z;
84     else
85         return z;
86 }
87